2010-01-14 54 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

它可以减少数据的大小,如果在名字报价在必要时

相关问题