你能解释一下JavaScript表达式:
[1 [{}]]
解析/求值?在Firefox,Chrome,Konqueror和rhino中,它似乎创建了一个包含单个元素undefined
的数组。但是,我不明白为什么。
在Firefox中:
[1 [{}]].toSource()
产生
[(void 0)]
将1替换为其他JavaScript值似乎会产生相同的结果。
更新:我想我现在明白了。 codeka,Adrian和CMS澄清了一些事情。至于标准,我试图通过ECMAScript 5。
1 [{}]
是一个属性访问器,因此在第11.2.1节中介绍。baseReference
是评估1
的结果,所以仍然是1
。baseValue = GetValue(baseReference) == 1
。GetValue
(§8.7.1),Type(1)
不是Reference
(已解析的名称绑定),因此请返回1. propertyNameReference
是评估{}
的结果,因此是一个空对象。propertyNameValue = GetValue(propertyNameReference) == {}
CheckObjectCoercible(baseValue)
(§9.10),我们返回(Number是对象可强制的)。propertyNameString = ToString(propertyNameValue)
ToString
(§9.8),返回ToString(ToPrimitive({}, hint String))
ToPrimitive
(§9.1),返回对象[[DefaultValue]]
的结果,传递PreferredType
(字符串)。[[DefaultValue]]
(§8.12.8),让toString成为带有参数[[Get]]
的{{1}}的结果。toString
,其中"[object " + [[Class]] + "]"
是默认对象原型的“Object”。 [[Class]]
,我们将其称为toString
this
。{}
类型的值,其基值为Reference
(1),其引用名称为BaseValue
(propertyNameString
)。然后我们转到Array初始化器(第11.1.4节),并用结果构造一个单独的元素数组。
答案 0 :(得分:15)
阅读OP and Nick comments,我想我可以再扩展Adrian's answer以使其更清晰。
这是完全有效的JavaScript。
JavaScript将对象属性名称作为字符串处理,对象不能包含其他类型或其他对象作为键,它们只是字符串。
括号表示法property accessor(MemberExpression [ Expression ]
)隐式将括号中的表达式转换为字符串,因此:
var obj = {};
obj[{}] = "foo";
alert(obj["[object Object]"]); // foo
在上面的示例中,您可以看到我为{}
属性分配了值,{}.toString()
(或{}+''
)生成了字符串"[object Object]
(来自{{ 3}})。
表达式1 [{}]
隐式地将1 Number
原语转换为对象(这是由属性访问器创建的),并且它查找名为"[object Object]"
的属性,在该对象上进行属性查找。 Number.prototype
和Object.prototype
个对象,例如:
1['toString'] === Number.prototype.toString; // true
最后,1 [{}]
表达式本身用括号([1 [{}]]
)括起来,这实际上是一个数组文字。
总之,解析器如何评估表达式:
[1 [{}]];
// ^ The accessor expression is evaluated and converted to string
[1 ["[object Object]"]];
// ^ A property lookup is made on an Number object
// trying to access a property named "[object Object]"
[undefined];
// ^ the property is obviously not found
[undefined];
//^ ^
// An array literal is created with an element `0` which its value is `undefined`
答案 1 :(得分:8)
这是因为您尝试获取对象{}
的属性1
,然后将其放入数组中。 1
没有属性{}
,因此1[{}]
为undefined
。
如果用数组替换1
,您将看到它是如何工作的。 1
为[5]
,{}
为0
,为[[5][0]]
。
另请注意,obj['property']
与obj.property
相同。
答案 2 :(得分:7)
如果我们稍微分解一下,你会看到:
var foo = 1;
var bar = {};
var baz = foo[bar];
[baz];
我相信它是有效的JavaScript,但我不是专家......