JavaScript表达式[1 [{}]]究竟是如何解析的?

时间:2010-06-21 00:20:19

标签: javascript parsing literals

你能解释一下JavaScript表达式:

[1 [{}]]

解析/求值?在Firefox,Chrome,Konqueror和rhino中,它似乎创建了一个包含单个元素undefined的数组。但是,我不明白为什么。

在Firefox中:

[1 [{}]].toSource()

产生

[(void 0)]

将1替换为其他JavaScript值似乎会产生相同的结果。

更新:我想我现在明白了。 codeka,Adrian和CMS澄清了一些事情。至于标准,我试图通过ECMAScript 5。

  1. 1 [{}]是一个属性访问器,因此在第11.2.1节中介绍。
  2. baseReference是评估1的结果,所以仍然是1
  3. baseValue = GetValue(baseReference) == 1
  4. GetValue(§8.7.1),Type(1)不是Reference(已解析的名称绑定),因此请返回1.
  5. propertyNameReference是评估{}的结果,因此是一个空对象。
  6. propertyNameValue = GetValue(propertyNameReference) == {}
  7. CheckObjectCoercible(baseValue)(§9.10),我们返回(Number是对象可强制的)。
  8. propertyNameString = ToString(propertyNameValue)
  9. ToString(§9.8),返回ToString(ToPrimitive({}, hint String))
  10. ToPrimitive(§9.1),返回对象[[DefaultValue]]的结果,传递PreferredType(字符串)。
  11. [[DefaultValue]](§8.12.8),让toString成为带有参数[[Get]]的{​​{1}}的结果。
  12. 这在§15.2.4.2中定义为返回toString,其中"[object " + [[Class]] + "]"是默认对象原型的“Object”。
  13. 由于有可调用的[[Class]],我们将其称为toString this
  14. 返回{}类型的值,其基值为Reference(1),其引用名称为BaseValuepropertyNameString)。
  15. 然后我们转到Array初始化器(第11.1.4节),并用结果构造一个单独的元素数组。

3 个答案:

答案 0 :(得分:15)

阅读OP and Nick comments,我想我可以再扩展Adrian's answer以使其更清晰。

这是完全有效的JavaScript。

JavaScript将对象属性名称作为字符串处理,对象不能包含其他类型或其他对象作为,它们只是字符串。

括号表示法property accessorMemberExpression [ Expression ])隐式将括号中的表达式转换为字符串,因此:

var obj = {};
obj[{}] = "foo";
alert(obj["[object Object]"]); // foo

在上面的示例中,您可以看到我为{}属性分配了值,{}.toString()(或{}+'')生成了字符串"[object Object](来自{{ 3}})。

表达式1 [{}]隐式地将1 Number原语转换为对象(这是由属性访问器创建的),并且它查找名为"[object Object]"的属性,在该对象上进行属性查找。 Number.prototypeObject.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,但我不是专家......