为什么javascript会将以下内容评估为true,因为对象foo
具有有效属性bar
?
foo[[[["bar"]]]] === foo["bar"]
基于运算符优先级,我认为foo[[[["bar"]]]]
正在尝试访问以数组[[["bar"]]]
为键的属性,但为什么它仍然“平坦化”为与{{1相同}}?
我的同事们说javascript解析器有简化括号,忽略了额外的括号。我不认为这是真的,因为将foo["bar"]
保存到变量[[["foo"]]]
会得到相同的结果:
test
语言或解析器的哪个方面导致此行为?谢谢!
答案 0 :(得分:7)
JavaScript括号表示法接受表达式,但它始终将该表达式的值转换为字符串。因此,如果传入一个数组,它将尝试将其转换为字符串。在您的情况下,您传入的是数组[[["bar"]]]
和[[["bar"]]].toString() === "bar"
。
如果您想知道为什么[[["bar"]]].toString() === "bar"
,那是因为当数组arr
被隐式转换为字符串时,就像调用arr.join(',')
一样。也就是说,它的每个元素都转换为字符串,然后以逗号分隔的字符串连接。当数组只有一个元素时,数组的字符串表示只是该元素的字符串表示。在您的情况下,您的数组([[["bar"]]]
)有一个元素:[["bar"]]
。
该数组也被转换为字符串,因为它也是一个单元素数组,所以它的字符串表示形式是该单个元素的字符串表示形式:["bar"]
。
["bar"]
也是一个包含一个元素的数组,它是一个字符串,因此["bar"]
的字符串表示只是"bar"
。
归结为:[[["bar"]]].toString() === "bar"
和foo[[[["bar"]]]]
与foo[[[["bar"]]].toString()]
相同。
你也会发现:
foo[[[[1]],[2]]] === foo["1,2"]
因为:[[[1]],[2]].toString() === "1,2"
。
答案 1 :(得分:6)
让我们逐步了解foo[[[["bar"]]]]
的评估方式:
foo[...]
中最外面的括号表示a property
accessor。表达式foo[[[["bar"]]]]
因此转换为
访问名为foo
的{{1}}媒体资源。
根据ECMA standard,抽象操作
然后使用ToPropertyKey(name)来更改名称[[["bar"]]]
进入属性键值:
属性键值是ECMAScript字符串值或符号 值。
名称[[["bar"]]]
不是符号类型,因此已转换
成一个字符串。数组由joining all its
string converted values转换为字符串:
[[["bar"]]]
这最终意味着我们的属性键实际上变为[[["bar"]]].toString() === "bar"
:
"bar"