JavaScript表达式[1[{}]]到底是如何解析的?
您能否解释一下JavaScript表达式是如何:JavaScript表达式[1[{}]]到底是如何解析的?,javascript,parsing,literals,Javascript,Parsing,Literals,您能否解释一下JavaScript表达式是如何: [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
[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`
解析/计算?在Firefox、Chrome、Konqueror和rhino中,它似乎创建了一个包含单个元素的数组,undefined
。然而,我不明白为什么
在Firefox中:
[1 [{}]].toSource()
产生
[(void 0)]
用其他JavaScript值替换1似乎会产生相同的结果
更新:我想我现在明白了。科德卡、阿德里安和CMS澄清了事情。就标准而言,我尝试遍历ECMAScript 5
1[{}]
是一个属性访问器,因此在§11.2.1中有介绍baseReference
是计算1
的结果,因此仍然是1
baseValue=GetValue(baseReference)==1
GetValue
(§8.7.1),类型(1)
不是参考(解析名称绑定),因此返回1
propertyNameReference
是计算{}
的结果,因此为空对象propertyNameValue=GetValue(propertyNameReference)=={}
checkObjectImprovalible(baseValue)
(§9.10)中,我们返回(数字是对象可强制的)propertyNameString=ToString(propertyNameValue)
ToString
(§9.8)中,返回ToString(ToPrimitive({},hint String))
ToPrimitive
(§9.1)中,返回对象的[[DefaultValue]]]
,传递首选类型
(字符串)[[DefaultValue]]
(§8.12.8)中,让toString是带有参数toString
的[[Get]]]
的结果“[object”+[[Class]]+“]”
,其中[[Class]]
是默认对象原型的“object”李>
toString
,我们用参数将其称为this
为{}
Reference
的值,其基值为BaseValue
(1),引用的名称为propertyNameString
(“[对象对象]”
)然后我们转到数组初始值设定项(§11.1.4),并用结果构造一个单元素数组。如果我们稍微分解一下,您将看到:
var foo = 1;
var bar = {};
var baz = foo[bar];
[baz];
我相信它是有效的JavaScript,但我不是专家…这是因为您试图获取对象
1
的属性{}
,然后将其放入数组中1
没有属性{}
,因此1[{}]
是未定义的
如果用数组替换1
,您将看到它是如何工作的。用1
作为[5]
和{}
作为0
,它就是[[5][0]
另外,请记住,obj['property']
与obj.property
阅读本文时,我想我可以进一步展开,使其更清晰
它是完全有效的JavaScript
JavaScript将对象属性名称作为字符串处理,对象不能包含其他类型或其他对象作为键,它们只是字符串
括号表示法(MemberExpression[Expression]
)将括号之间的表达式隐式转换为字符串,因此:
var obj = {};
obj[{}] = "foo";
alert(obj["[object Object]"]); // foo
在上面的示例中,您可以看到我为{}
属性赋值,并且{}.toString()
(或{}+'
)生成字符串“[object object]
(via)
表达式1[{}]
隐式地将1Number
原语转换为对象(由属性访问器生成),并查找名为“[object object]”的属性。
对Number.prototype
和对象进行属性查找。例如,prototype
对象:
1['toString'] === Number.prototype.toString; // true
最后,1[{}]
表达式本身被括在括号中([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`
我不确定为什么这会是有效的JavaScript…所以引擎尝试处理它时会得到不可预测的结果…我觉得状态正常。@Nick,我也怀疑它是否是有效的JS,我愿意接受它只是未定义行为的可能性。然而,事实上,所有4个引擎(都有单独的实现)用同样的方式解析它至少很有趣。@Matthew-Adrian的回答很好地解释了这4种浏览器的行为,我仍然不认为[object]
是一个有效的访问器,但…所以它如何处理这个问题仍然取决于每个引擎。虽然这是一个边缘问题,但我在3.1规范中找不到任何说明应该如何正确处理它的内容。@Nick,它似乎至少对ECMAScript 5有效。我试着在上面介绍它。@Nick:[对象]
是有效的,但是对象将被转换为字符串。我想你已经看到了。我可能没有看到这一点,因为使用数字作为JavaScript对象是不寻常的,而空对象是不寻常的键。你对[(void 0)]
部分有什么想法吗?@Matthew:我猜是因为1[{}]
是未定义的,(void 0)
只是解释程序表示“未定义”的“规范”形式。