JSON'da neden her bir isim alıntılanıyor?


91

JSON spesifikasyonu , JSON'un bir nesne veya bir dizi olduğunu söylüyor. Bir nesne olması durumunda,

Bir nesne yapısı, sıfır veya daha fazla ad / değer çiftini (veya üyelerini) çevreleyen bir çift küme parantez olarak temsil edilir. Bir isim bir dizedir. ...

Ve daha sonra, teknik özellik bir dizenin tırnak içine alındığını söylüyor.

Neden?

Böylece,

{"Property1":"Value1","Property2":18}

ve yok

{Property1:"Value1",Property2:18}

Soru 1 : Neden ad / değer çiftlerindeki adın tırnaksız tanımlayıcılar olmasına izin vermiyorsunuz?


Soru 2 : Javascript ile değerlendirildiğinde yukarıdaki iki temsil arasında anlamsal bir fark var mı?


1
@Bruno: Sen XML aynı şekilde konuşabilir ... ve ne yazık ki, orada bazı iyi ... Bir programlama dili olarak kullanılması XML çalışıyor olabilirsiniz
Mike DeSimone

2
+1 ... tuhaf bir çelişki gibi görünüyor .... "tırnak işaretleri" onu standart JSON yapar, ancak çalışmaz eval()(yani javascript).
skaffman

2
@bruno, hayır. genişletirseniz, "Javascript Nesne Gösteriminde" olur ki bu iyi bir şey
Dave Archer

2
@skaffman - JavaScript'te değerlendirildiğinde çalışacak.
Quentin

1
@Bruno - JSON bir veri formatıdır. "JSON'da" - spesifikasyona göre biçimlendirilmiş veriler anlamına gelir.
Cheeso

Yanıtlar:


57

Soru 1: Neden ad / değer çiftlerindeki adın tırnaksız tanımlayıcılar olmasına izin vermiyorsunuz?

JSON'un tasarım felsefesi "Basit tutun"

"İle alıntı adları "" çok daha basittir Sen isimleri teklif verebilir" "ya 'ama belli karakterler (ya da bir anahtar kelime yapacak karakter birleşimi) ve ihtiva sürece, gerekmez 'ya "gerekebilir bağlı alıntı edilecek hangi sınırlayıcıyı seçtiğinizde " .

Soru 2: Javascript ile değerlendirildiğinde yukarıdaki iki temsil arasında anlamsal bir fark var mı?

Hayır. JavaScript'te aynıdırlar.


3
Hayır bu doğru değil. CMS'nin doğru cevabı var. Bu cevap, gerçek nedenin güzel bir yan etkisidir. Açıklamanın daha basit olmasının yanı sıra, tanımlayıcılardaki dizeler için ayrıştırma kurallarını yeniden kullanabileceğiniz için ayrıştırıcı yazmak da daha kolaydır.
Breton

ve bunun dışında, bir tanımlayıcının ayrılmış bir kelime olması durumunda, bir tanımlayıcı yerine o kelime olarak yorumlanmasında küçük bir anlamsal fark vardır.
Breton

2
CMS'nin cevabında +1, bu doğru. Çift tırnak bir kod kuralı değildir, ancak nesnede anahtar olarak ayrılmış sözcüklerden kaçınmak istersiniz. Örneğin: {property1: "abc", bu: "def"} YANLIŞ (bu ayrılmış bir anahtar kelimedir)
Sorin Mocanu

Soru 2 : JSON.parseİşlev kullanılırken Javascript'te küçük bir fark var :JSON.parse('{"a":1}') iyi çalışıyor neden JSON.parse('{a:1}')olacak bir istisna .
nhnghia

@nhnghia - Soru 2, kaynak kodunu JSON olarak değil JavaScript olarak değerlendirmekle ilgili . JSON.parseJavaScript'te uygulanan bir JSON ayrıştırıcısıdır, JavaScript ayrıştırıcısı değildir.
Quentin

134

Douglas Crockford'un (JSON standardının yaratıcısı) Yahoo'ya verdiği bir sunumdan bir alıntı bırakıyorum.

JSON'u nasıl keşfettiğinden ve diğer şeylerin yanı sıra neden alıntılanmış anahtarları kullanmaya karar verdiğinden bahsediyor :

.... O zaman alıntılanmamış isim problemini keşfettik. Görünüşe göre ECMA Script 3, rezerve edilmiş bir kelime politikasına sahip. Ayrılmış kelimelerin anahtar konumda alıntılanması gerekir ki bu gerçekten bir sıkıntıdır. Bunu bir standart haline getirmeye başladığımda, tüm ayrılmış kelimeleri standarda koymak zorunda kalmak istemedim çünkü bu gerçekten aptalca görünürdü.

O zamanlar insanları ikna etmeye çalışıyordum: evet, JavaScript'te uygulamalar yazabilirsiniz, aslında işe yarayacak ve bu iyi bir dil. Öyleyse aynı anda söylemek istemedim: ve yaptıkları şu aptalca şeye bak! Ben de bunun yerine anahtarları aktarmaya karar verdim.
Bu şekilde, ne kadar saçma olduğunu kimseye söylememize gerek kalmaz.

Bu nedenle, bu güne kadar anahtarlar JSON'da alıntılanıyor.

Videonun tamamını ve konuşma metnini burada bulabilirsiniz .


Ummm ... JSON standardının yaratıcısı mı? Bunun abartılı bir ifade olduğuna inanıyorum. JSON, JavaScript Nesne Gösterimi'dir ve Javascript (ECMA) spesifikasyonundan gelir.
Sorin Mocanu

42
@Sorin: JSON'u JavaScript Nesne değişmez değerleri ile karıştırmayın. JSON, Crockford tarafından 2006'da önerilen, dilden bağımsız bir veri değişim formatıdır ( tools.ietf.org/html/rfc4627 ), grameri JavaScript Nesnesi değişmezlerinden ( bclary.com/2004/11/07/#a-11.1 ) farklıdır. .5 ), temelde yalnızca dize anahtarlarına ve değerlere izin verilmesi ZORUNLU , bir nesne , dizi , sayı , dize veya şu değişmez adlardan biri olmalıdır: false , null true . JavaScript'teki nesne değişmez değerleri, Tanımlayıcılar , Dize değişmezleri veyaSayı değişmezleri ve değer herhangi bir ifade türü olabilir ...
Christian C. Salvadó

@CMS Ve bugünün JavaScript'i, nesne oluşturucu ifadeleri içinde kısa tanımlayıcılara izin verir, örneğin:, { a }burada 'a' özelliği, genel veya yerel bir değişken 'a' değerini kopyalar.
Hydroper

@CMS Ve orada da bilgisayarlı oluyor tuşları:{[key]: value}
Hydroper

0

:Tanımlayıcılarda hem boşluklara hem de boşluklara izin verilir. Tırnak işaretleri olmadan bu, tanımlayıcıyı tam olarak neyin oluşturduğunu belirlemeye çalışırken belirsizliğe neden olur.


0

JavaScript'te nesneler, anahtar çiftleri ile bir hash / hashtable gibi kullanılabilir.

Bununla birlikte, anahtarınızda javascript'in ad olarak belirtemediği karakterler varsa, anahtar yerine bir nesne üzerindeki bir özellik gibi erişmeye çalışırken başarısız olur.

var test  = {};
test["key"] = 1;
test["#my-div"] = "<div> stuff </div>";

// test = { "key": 1, "#my-div": "<div> stuff </div>" };

console.log(test.key);           // should be 1
console.log(test["key"]);        // should be 1
console.log(test["#my-div"]);    // should be "<div> stuff </div>";
console.log(test.#my-div);       // would not work.

tanımlayıcılar bazen javascript'te belirteç / tanımlayıcı olarak değerlendirilemeyen karakterlere sahip olabilir, bu nedenle tutarlılık için tüm tanımlayıcıları dizelere koymak en iyisidir.


-2

Bence Cheeso'nun sorusuna verilecek doğru cevap, uygulamanın dokümantasyonu aşmasıdır. Artık anahtar olarak bir dize gerektirmez, daha çok bir dize (yani tırnaklı) veya (muhtemelen) değişken adı olarak kullanılabilecek herhangi bir şey olabilir, ki bunun bir harfle başlaması anlamına geldiğini tahmin edeceğim, _ veya $ ve yalnızca harfleri, sayıları ve $ ve _ karakterlerini içerir.

Geri kalanını, bu soruyu ziyaret eden bir sonraki kişi için yaptığım aynı fikirle basitleştirmek istedim. İşte et:

Nesne anahtarı olarak kullanıldığında, değişken adları JSON'da enterpolasyonlu değildir (Teşekkürler Friedo!)

Breton, "anahtar" yerine "tanımlayıcı" kullanarak "eğer bir tanımlayıcı ayrılmış bir kelime ise, bir tanımlayıcı olarak değil o kelime olarak yorumlanır" diye yazmıştır. Bu doğru olabilir, ama hiç sorun yaşamadan denedim:

var a = {do:1,long:2,super:3,abstract:4,var:5,break:6,boolean:7};
a.break

=> 6

Quentin, tırnak işaretleri kullanma hakkında "... [anahtar] belirli karakterleri (veya onu bir anahtar kelime yapacak karakter kombinasyonlarını ) içermediği sürece " ...

@ İşaretini kullanarak önceki kısmın (belirli karakterlerin) doğru olduğunu buldum (aslında, hataya neden olmayan tek karakterlerin $ ve _ olduğunu düşünüyorum):

var a = {a@b:1};

=> Sözdizimi hatası

var a = {"a@b":1};
a['a@b']

=> 1

ancak yukarıda gösterdiğim gibi, anahtar kelimelerle ilgili parantez doğru değil.

İstediğim şey işe yarıyor çünkü açılış {ve iki nokta üst üste arasındaki veya sonraki özellikler için virgül ve iki nokta üst üste arasındaki metin, bir nesne anahtarı oluşturmak için tırnaksız bir dize olarak kullanılıyor veya Friedo'nun dediği gibi, bir değişken adı yok ' t enterpolasyonlu olsun:

var uid = getUID();
var token = getToken();            // Returns ABC123
var data = {uid:uid,token:token};
data.token

=> ABC123


-3

Eğer json nesneleri tanımlıyorsa, pratikte aşağıdakileri elde edersiniz

var foo = {};

var bar = 1;

foo["bar"] = "hello";
foo[bar] = "goodbye";

e sonra,

foo.bar == "hello";
foo[1] == "goodbye" // in setting it used the value of var bar

yani örnekleriniz aynı sonucu verse bile, "ham kod" daki eşdeğerleri vermez. Belki de bu yüzdendir?? dunno, sadece bir fikir.


3
@David, değişken adları bir nesne anahtarı olarak kullanıldığında JS'de enterpolasyonlu değildir. { bar: 'goodbye' }anahtar adını değerine ayarlamayacak, barsadece olacaktır bar. Diğerleri, spesifikasyonun tırnak gerektirmesinin nedeni konusunda haklıdır: anahtar kelime ve özel karakter çatışmalarından kaçınmaktır.
friedo

-3

İsimdeki alıntılara yalnızca gerekli olduğunda izin verilirse veri boyutunu azaltabilir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.