2010-01-14 68 views
78

The JSON spec表示JSON是一個對象或數組。對於對象,,爲什麼引用每個名稱?

對象結構表示爲圍繞零個或多個名稱/值對(或成員)的一對大括號 。 名稱是 字符串。 ...

而後來,規範說明字符串被引號括起來。

爲什麼?

因此,

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

,而不是

{Property1:"Value1",Property2:18} 

問題1:爲什麼不允許在名稱/值對的名稱是加引號的標識符?


問題2:是否有以上兩種表述之間的語義差別,在Javascript評估是什麼時候?

+0

你是什麼意思「的JSON」的意思是隻允許?它使「JSON」看起來像一種編程語言。 – 2010-01-14 22:21:33

+1

@布魯諾:你可以用同樣的方式談論XML ......可悲的是,有些人可能會嘗試使用XML作爲編程語言...... – 2010-01-14 22:24:48

+2

+1 ......它看起來像一個奇特的矛盾。 ..「帶引號」使其成爲標準的JSON,但不會與'eval()'(即javascript)一起使用。 – skaffman 2010-01-14 22:24:55

回答

53

問題1:爲什麼不讓名稱/值對中的名稱成爲不帶引號的標識符?

JSON的設計理念是「保持簡單」

「與"報價名稱」是簡單了很多比「你們可以引用名稱與"',但你沒有除非它們包含某些字符(或將使其成爲關鍵字的字符組合),並且'"可能需要引用,具體取決於您選擇的分隔符「」。

問題2:有沒有上面的兩個表示之間的語義差別,在Javascript評估是什麼時候?

不。在JavaScript中它們是相同的。

+2

不,這是不正確的。 CMS有正確的答案。這個答案只是真正原因的一個很好的副作用。除了更簡單的解釋之外,編寫解析器也更簡單,因爲您可以在標識符上重複使用字符串的解析規則。 – Breton 2010-01-14 23:14:02

+0

除此之外,如果一個標識符碰巧是一個保留字,就會有輕微的語義差異,因此它被解釋爲該字而不是標識符。 – Breton 2010-01-14 23:26:34

+2

CMS的答案+1,這是正確的。雙引號不是代碼約定,但您希望避免保留字作爲對象中的鍵。 例如: {property1:「abc」,this:「def」}是錯誤的 (這是一個保留關鍵字) – 2010-01-15 11:21:48

0

標識符中允許使用:和空格。如果沒有引號,這會在嘗試確定標識符的確切構成時造成歧義。

125

我從道格拉斯克羅克福德(JSON標準的創建者)給雅虎的演示中引用了一段話。

他談到他如何發現 JSON,以及除其他事項外,爲什麼他決定用引述鍵

.... 那是當我們發現 不帶引號的名稱問題。事實證明, ECMA腳本3有一個重擊保留 字策略。保留字必須是 所引用的關鍵位置,這對 真是一個滋擾。當我使用 將其標準化時,I 不想將所有 保留字放在標準中,因爲它看起來非常愚蠢。

當時,我正試圖說服 人:是的,你可以使用JavaScript編寫的應用 ,它實際上 去工作,這是一個很好的 語言。我不想說,那麼, 在同一時間:看看這個 他們真的很愚蠢的事情!所以我決定,我只是引用 鍵。
這樣,我們不必告訴 任何人關於它是多麼的重要。

這就是爲什麼,爲了這一天,按鍵均以 JSON。

你可以找到完整的視頻和成績單here

+0

嗯...... JSON標準的* creator *!我相信這是多餘的。 JSON是JavaScript對象表示法,來自Javascript(ECMA)規範。 – 2010-01-15 11:22:47

+39

@Sorin:不要將JSON與JavaScript Object文字混淆。 JSON是一種與語言無關的數據交換格式,由Crockford於2006年提出(http://tools.ietf.org/html/rfc4627),其語法不同於JavaScript Object literals(http://bclary.com/2004/ 11/07 /#a-11.1.5),基本上只允許*字符串*鍵和值*必須是*對象*,*數組*,*數字*,*字符串*或以下文字之一名稱:* false *,* null * * true *。 JavaScript中的對象文字可以具有*標識符*,*字符串文字*或*數字文字*作爲鍵,並且該值可以是任何類型的*表達式* ... – CMS 2010-01-15 21:23:09

+0

@CMS今天的JavaScript允許對象構造函數表達式中的速記標識符,例如:'{a}',其中屬性'a'複製全局或局部變量'a'的值。 – Hydro 2016-10-27 21:43:45

-3

如果JSON介紹對象,然後在實踐中得到以下

var foo = {}; 

var bar = 1; 

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

這樣的話,

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

所以即使你的例子確實產生相同的結果,他們的「原始代碼等效「不會。也許這就是爲什麼?不知道,只是一個想法。

+3

@David,當用作對象鍵時,變量名不會在JS中進行插值。 '{bar:'goodbye'}'不會將鍵名設置爲'bar'的值,它只會是'bar'。其他人對規範要求引用的原因是正確的:避免關鍵字和特殊字符衝突。 – friedo 2010-01-14 23:07:27

0

在JavaScript對象可以像使用密鑰對的散列/散列表一樣使用。

但是,如果你的密鑰有JavaScript的無法記號化作爲名稱的字符,它會嘗試它像一個對象的屬性,而不是一鍵訪問時失敗。

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. 

標識符有時可以具有可以不是作爲在JavaScript的令牌/標識符來評測的字符,因此它的最好把所有標識符中的字符串的一致性。

-1

我認爲Cheeso問題的正確答案是實現超過了文檔。它不再需要一個字符串作爲關鍵字,而是需要其他東西,它可以是一個字符串(即引號)或(可能)任何可以用作變量名的東西,我猜測它意味着以字母開頭,_或$,只包括字母,數字和$和_。

我想簡化休息誰訪問與我一樣的想法這個問題,旁邊的人。這裏的肉:

變量名沒有在JSON插值爲對象鍵(!感謝Friedo)

布列塔尼,使用「標識」,而不是「關鍵」,寫時說:「如果一個標識符恰好是一個保留字,它被解釋爲該字而不是標識符。「這可能是真的,但我想它沒有任何麻煩:

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

=> 6

關於使用引號,昆汀寫道:」 ......但你不就得了,除非[關鍵]包含某些字符(或字符的組合,這將使它關鍵字)」

我找到了前半部分(某些字符)爲真,用@符號(其實我覺得$和_是隻有不會導致錯誤的字符):

var a = {[email protected]:1}; 

=>語法錯誤

var a = {"[email protected]":1}; 
a['[email protected]'] 

=> 1

但括號關於關鍵字,如我上面顯示,是不正確的。

我想要的作品是因爲開頭{和冒號之間的文本,或者逗號和冒號之間的文本被用作不帶引號的字符串來創建對象鍵,或者像弗裏多所說的那樣,它是一個變量名字裏有沒有得到插值:

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

=> ABC123

-2

它可以減少數據的大小,如果在名字報價在必要時

相關問題