这个 JavaScript 对象字面量键的限制严格是由解析引起的吗?

10
请参考下面的代码,当我“取消注释”任何一个被注释的行时,会导致错误(在IE中),错误为“预期‘:’”。那么我的结论是正确的吗?不能将对象值作为对象键提供给字符串文字,这是一个解释器/解析问题吗?相比Crockford的“好部分”,这是否是JavaScript中可怕(或至少是“糟糕”的)“部分”的候选?
<script>
var keys = {'ONE': 'one'};

//causes error:
//var obj1 = {keys.ONE: 'value1'};
//var obj1 = {keys['ONE']: 'value1'};

//works
var obj1 = {};
obj1[keys.ONE] = 'value1';

//also works
var key_one = keys.ONE;
var obj2 = {key_one: 'value1'};
</script>

1
顺便提一下,var key_one = keys.ONE; var obj2 = {key_one: 'value1'}; 并不像你期望的那样工作。obj2 的属性将是 key_one 而不是 key.ONE 的值,因此也不是 one - RoToRa
1
请注意,尽管最后一个示例可以工作,但它创建了一个具有属性“key_one”的对象,而不是属性“keys.One”。变量“key_one”与下一行中的文字对象无关。 - Guffa
1
它们已经在JSON规范中被禁止。但是JavaScript对象可以定义方法,如{somevar: 1, methodname:function(){ /*stuff*/ } },我想有人不喜欢将他的方法名用引号括起来;) - naugtur
@George:或者他们可以像其他一些语言一样,在对象字面量中禁止引用名称... - Guffa
可能是JavaScript对象键使用变量的重复问题。 - Bergi
显示剩余2条评论
4个回答

15

字面对象语法的限制是名称必须是文字。因为名称既可以指定为标识符,也可以指定为字符串,所以无法使用变量。

这将创建一个带有属性 n 的对象,而不是属性 answer

var n = 'answer';
var o = { n: 42 };

数字字面量同样可以作为有效的属性名称。此外,在ES5中,这些名称可以被指定为标识符名称(即不仅限于标识符,还包括保留字)。请参见https://dev59.com/QW855IYBdhLWcg3wbztk#9568622。 - Mathias Bynens

6

当使用 {} 定义对象时,不能将变量用作键。

因此,它们被解释为字符串名称,并且只能由可用于变量名称的字符组成。

使用 objectname[anythingThatReturnsValue]='value1'; 即可解决问题。

另外,您可以生成一个字符串并对其进行解析。

var s='{"'+keys.ONE+'": "value1"}';
var obj=JSON.parse(s);
//or
s='var obj2='+s;
eval(s);

以上两种方法都是在JavaScript中创建对象的不良实践,我不建议使用它们。


在使用{}定义对象时,您可以将变量用作键,参见第二个“也可以”块。 - Dexygen
1
@George:不行,你不能这样做。代码可以运行,但它没有在字面对象中使用该变量。 - Guffa
2
@George - 为了明确:var obj2 = {key_one: 'value1'};var obj2 = {"key_one": 'value1'}; 是相同的 - key_one 将是该字段的名称。 - naugtur
@naugtur:对于 JSON,我认为您还必须引用键var s = '{" + keys.ONE + ':"value1"}'; - vol7ron
不是有意提出一个旧答案,只是看到这个经过 :) - vol7ron
显示剩余2条评论

2
想一想:如果它按照你的想法工作,那么就会完全引入语言歧义。
var obj = {something:"red"}
var obj = {"something":"red"}

这两个语句在JavaScript中是等价的,因为裸字键会自动加引号。因此,如果 something 表示字面字符串 "something",它怎么可能也指代变量 "something" 呢?不可能。所以,如果你想使用变量,它们必须放在方括号表示法中,而不是 key : value 表示法中。

1

您可以尝试以下方法:

var obj = {};
var val = 'foo';

obj[val] = 'bar'; 

obj.foo >>> 'bar';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接