The JSON spec表示JSON是一个对象或数组。在对象的情况下,
对象结构表示为一对花括号 包含零个或多个名称/值对(或成员)。 名字是 字符串。 ...
之后,该规范称一个字符串被引号括起来。
为什么呢?
因此,
{"Property1":"Value1","Property2":18}
而不是
{Property1:"Value1",Property2:18}
问题1 :为什么不允许名称/值对中的名称是不带引号的标识符?
问题2 :在Javascript中评估时,上述两种表示之间是否存在语义差异?
答案 0 :(得分:131)
我从Douglas Crockford(JSON标准的创建者)给雅虎的演讲中引用了一句话。
他谈到了他如何发现 JSON,以及其他为什么他决定使用引用的密钥:
.... 那是我们发现的时候 不带引号的名称问题。事实证明 ECMA脚本3有一个保留的whack 字政策。保留字必须是 引用关键位置,这是 真的很麻烦。当我到处走走时 把它公式化成一个标准,我 不想要把所有的 标准中的保留字, 因为它看起来真的很蠢。
当时,我试图说服 人:是的,你可以写 JavaScript中的应用程序,它是 实际上去工作,这是一个很好的 语言。那时我不想说 在同一时间:看看这个 他们真的很蠢!所以我 相反,我们决定引用它 键。
那样,我们不必告诉 任何关于它是如何打击的人。这就是为什么,直到今天,还引用了密钥 JSON。
您可以找到完整的视频和文字记录here。
答案 1 :(得分:56)
问题1:为什么不允许名称/值对中的名称是不带引号的标识符?
JSON的设计理念是“保持简单”
“引用名称"
”比简单得多“您可以使用"
或'
引用名称但不要必须,除非它们包含某些字符(或使其成为关键字的字符组合),并且可能需要引用'
或"
,具体取决于您选择的分隔符“。< / p>
问题2:在Javascript中评估时,上述两种表示之间是否存在语义差异?
没有。在JavaScript中,它们完全相同。
答案 2 :(得分:0)
标识符中允许:
和空格。如果没有引号,在尝试确定标识符的确切构成时,这会导致歧义。
答案 3 :(得分: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中作为标记/标识符进行求值的字符,因此最好将所有标识符放在字符串中以保持一致性。
答案 4 :(得分:-1)
我认为Cheeso问题的正确答案是实施超出了文档。它不再需要字符串作为键,而是需要其他东西,它可以是一个字符串(即引用)或(可能)任何可以用作变量名称的东西,我猜这意味着以字母开头,_或$,仅包括字母,数字和$和_。
我希望为下一个访问此问题的人简化剩下的工作,我的想法与此相同。这是肉:
当用作对象键时,变量名不以JSON插值(感谢Friedo!)
布列塔尼使用“标识符”代替“密钥”,写道“如果标识符碰巧是保留字,则将其解释为该字而不是标识符。”这可能是真的,但我没有遇到任何麻烦:
var a = {do:1,long:2,super:3,abstract:4,var:5,break:6,boolean:7};
a.break
=&GT; 6
关于使用引号,Quentin写道“......但除非[键]包含某些字符(或使其成为关键字的字符组合),否则您不必使用”< / p>
我发现前一部分(某些字符)是真的,使用@符号(事实上,我认为$和_是唯一不会导致错误的字符):
var a = {a@b:1};
=&GT;语法错误
var a = {"a@b":1};
a['a@b']
=&GT; 1
但正如我上面所示,关于关键字的括号内容并非如此。
我想要的是因为开头{和冒号之间的文本,或逗号和冒号之间的文本用于后续属性被用作不带引号的字符串来创建对象键,或者,正如弗里多所说,它是一个变量名称没有插值:
var uid = getUID();
var token = getToken(); // Returns ABC123
var data = {uid:uid,token:token};
data.token
=&GT; ABC123
答案 5 :(得分:-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
所以即使你的例子产生相同的结果,它们在“原始代码”中的等价物也不会。也许这就是为什么?不知道,只是一个想法。
答案 6 :(得分:-3)
如果仅在必要时允许名称上的引号,则可能会减少数据大小