对象[[[“key”]]]如何在javascript中评估对象[“key”]?

时间:2016-06-10 22:17:30

标签: javascript arrays accessor

为什么javascript会将以下内容评估为true,因为对象foo具有有效属性bar

foo[[[["bar"]]]] === foo["bar"]

基于运算符优先级,我认为foo[[[["bar"]]]]正在尝试访问以数组[[["bar"]]]为键的属性,但为什么它仍然“平坦化”为与{{1相同}}?

我的同事们说javascript解析器有简化括号,忽略了额外的括号。我不认为这是真的,因为将foo["bar"]保存到变量[[["foo"]]]会得到相同的结果:

test

语言或解析器的哪个方面导致此行为?谢谢!

2 个答案:

答案 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"]]]]的评估方式:

  1. foo[...]中最外面的括号表示a property accessor。表达式foo[[[["bar"]]]]因此转换为 访问名为foo的{​​{1}}媒体资源。

  2. 根据ECMA standard,抽象操作 然后使用ToPropertyKey(name)来更改名称[[["bar"]]] 进入属性键值

      

    属性键值是ECMAScript字符串值或符号   值。

    名称[[["bar"]]]不是符号类型,因此已转换 成一个字符串。数组由joining all its string converted values转换为字符串:

    [[["bar"]]]
  3. 这最终意味着我们的属性键实际上变为[[["bar"]]].toString() === "bar"

    "bar"