JavaScript 如何使用数组初始化对象?

3
> a = ["key","value"]
["key", "value"]
> o = {a[0]:a[1]}
SyntaxError: Unexpected token [

但这没问题

> o = {}
Object {}
> o[a[0]] = a[1];
"value"
> o
Object {key: "value"}

浏览器版本:Chrome 37.0.2062.124 m

为什么会出现语法错误? 是不是引入了新的上下文?我不熟悉 ECMA 规范。

3个回答

5
根据ECMA Script 5.1规范,对象字面量的定义如下:
ObjectLiteral :
        { }
        { PropertyNameAndValueList }
        { PropertyNameAndValueList , }

PropertyNameAndValueList :
        PropertyAssignment
        PropertyNameAndValueList , PropertyAssignment

PropertyAssignment :
        PropertyName : AssignmentExpression
        get PropertyName ( ) { FunctionBody }
        set PropertyName ( PropertySetParameterList ) { FunctionBody }

PropertyName :
        IdentifierName
        StringLiteral
        NumericLiteral

PropertySetParameterList :
        Identifier

由于[]IdentifierNameStringLiteralNumericLiteral中都不被允许,因此JavaScript引擎无法解析该代码。这就是为什么它会报语法错误的原因。
因此,要从数组创建一个具有键和值的对象,您需要先构造对象,然后逐个分配属性,例如:
var newObject = {};
newObject[arr[0]] = arr[1];

5

在对象字面量中,属性名称必须是标识符(foo)、字符串字面量("foo")或数字字面量(1)。a[0] 不属于这些类型之一。

当你向现有对象添加属性时,需要使用方括号语法,然后使用可评估为字符串的表达式(a[0] 就是其中之一)。

如果要使用表达式设置属性名称,则必须先构建对象,然后在另一个语句中添加属性。


1
在ES6中,您有“计算属性名”(参见http://www.ecma-international.org/ecma-262/6.0/):
PropertyName : See 12.2.6
    LiteralPropertyName
    ComputedPropertyName
LiteralPropertyName : See 12.2.6
    IdentifierName
    StringLiteral
    NumericLiteral
ComputedPropertyName : See 12.2.6
    [ AssignmentExpression ]

这意味着,当您将[Expression]作为键编写时,而不是StringLiteralNumberLiteralIdentifierName,表达式将被评估并用作键。就像这样:
> a=["key", "value"]
["key", "value"]
> o={[a[0]]: a[1], [3*3]: "hello"}
Object {key: "value", 9: "hello"}

请注意,ES6仍然没有得到全面支持。如果不支持该功能,请在对象创建后分配值(就像您的第二个示例中一样)。

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