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

时间:2022-03-05 23:44:59

This question already has an answer here:

这个问题在这里已有答案:

Why does javascript evaluate the following as true, given that object foo has a valid property bar?

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

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

Based on operator precedence, I would think foo[[[["bar"]]]] is trying to access a property with the array [[["bar"]]] as the key, but why does that still "flatten down" to the same as foo["bar"]?

基于运算符优先级,我认为foo [[[[“bar”]]]]试图以数组[[[“bar”]]]作为键来访问属性,但为什么它仍然“平坦化” “就像foo [”bar“]一样?

Colleagues of mine are saying javascript parsers have bracket simplifying which ignores the extra brackets. I don't think this is true since saving [[["foo"]]] to a variable test gives the same result:

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

> test = [[["bar"]]]
 [Array[1]]
> foo["bar"] = 5
 5
> foo[test]
 5

What aspect of the language or parser is causing this behavior? Thanks!

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

2 个解决方案

#1


7  

JavaScript bracket notation accepts an expression, but it always converts the value of that expression to a string. Thus if you pass in an array, it will attempt to convert it to a string. In your case you are passing in an array [[["bar"]]], and [[["bar"]]].toString() === "bar".

JavaScript括号表示法接受表达式,但它始终将该表达式的值转换为字符串。因此,如果传入数组,它将尝试将其转换为字符串。在你的情况下,你传入一个数组[[[“bar”]]]和[[[“bar”]]]。toString()===“bar”。

If you are wondering why [[["bar"]]].toString() === "bar", it is because when an array arr is converted to a string implicitly it is like calling arr.join(','). That is each of its elements are converted to strings and then joined in a comma separated string. When the array only has one element, the string representation of the array is just the string representation of that one element. In your case your array ([[["bar"]]]) has one element: [["bar"]].

如果你想知道为什么[[[“bar”]]]。toString()===“bar”,那是因为当数组arr被隐式转换为字符串时,就像调用arr.join(',') 。也就是说,它的每个元素都被转换为字符串,然后以逗号分隔的字符串连接。当数组只有一个元素时,数组的字符串表示只是该元素的字符串表示。在您的情况下,您的数组([[[“bar”]]])有一个元素:[[“bar”]]。

That array is converted to a string too, and since it is also a one element array, the string representation of it is the string representation of that single element: ["bar"].

该数组也被转换为字符串,因为它也是一个单元素数组,它的字符串表示形式是该单个元素的字符串表示形式:[“bar”]。

["bar"] is also an array with one element, which is a string, so the string representation of ["bar"] is just "bar".

[“bar”]也是一个带有一个元素的数组,它是一个字符串,因此[“bar”]的字符串表示只是“bar”。

What this comes down to is: [[["bar"]]].toString() === "bar"

这归结为:[[[“bar”]]]。toString()===“bar”

and foo[[[["bar"]]]] is the same as foo[[[["bar"]]].toString()].

和foo [[[[“bar”]]]]与foo [[[[“bar”]]]。toString()]相同。

You would also find that:

您还会发现:

foo[[[[1]],[2]]] === foo["1,2"]

because: [[[1]],[2]].toString() === "1,2".

因为:[[[1]],[2]]。toString()===“1,2”。

#2


6  

Let's see how foo[[[["bar"]]]] is evaluated, step-by step:

让我们看看如何评估foo [[[[“bar”]]]]的步骤:

  1. The outermost brackets in foo[...] denote a property accessor. The expression foo[[[["bar"]]]] thus translates to accessing a property of foo with name [[["bar"]]].

    foo [...]中最外面的括号表示属性访问器。表达式foo [[[[“bar”]]]]因此转换为访问名为[[[“bar”]]]的foo属性。

  2. According to the ECMA standard, the abstract operation ToPropertyKey(name) is then used to turn the name [[["bar"]]] into a property key value:

    根据ECMA标准,抽象操作ToPropertyKey(name)然后用于将名称[[[“bar”]]]转换为属性键值:

    A property key value is either an ECMAScript String value or a Symbol value.

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

    The name [[["bar"]]] is not of type Symbol and thus converted into a string. An array is converted to a string by joining all its string converted values:

    名称[[[“bar”]]]不是Symbol类型,因此转换为字符串。通过连接其所有字符串转换值,将数组转换为字符串:

    [[["bar"]]].toString() === "bar"
    
  3. Which finally means that our property key actually becomes "bar":

    这最终意味着我们的属性键实际上变成了“bar”:

    foo[[[["bar"]]]] === foo[[[["bar"]]].toString()] === foo["bar"]
    

#1


7  

JavaScript bracket notation accepts an expression, but it always converts the value of that expression to a string. Thus if you pass in an array, it will attempt to convert it to a string. In your case you are passing in an array [[["bar"]]], and [[["bar"]]].toString() === "bar".

JavaScript括号表示法接受表达式,但它始终将该表达式的值转换为字符串。因此,如果传入数组,它将尝试将其转换为字符串。在你的情况下,你传入一个数组[[[“bar”]]]和[[[“bar”]]]。toString()===“bar”。

If you are wondering why [[["bar"]]].toString() === "bar", it is because when an array arr is converted to a string implicitly it is like calling arr.join(','). That is each of its elements are converted to strings and then joined in a comma separated string. When the array only has one element, the string representation of the array is just the string representation of that one element. In your case your array ([[["bar"]]]) has one element: [["bar"]].

如果你想知道为什么[[[“bar”]]]。toString()===“bar”,那是因为当数组arr被隐式转换为字符串时,就像调用arr.join(',') 。也就是说,它的每个元素都被转换为字符串,然后以逗号分隔的字符串连接。当数组只有一个元素时,数组的字符串表示只是该元素的字符串表示。在您的情况下,您的数组([[[“bar”]]])有一个元素:[[“bar”]]。

That array is converted to a string too, and since it is also a one element array, the string representation of it is the string representation of that single element: ["bar"].

该数组也被转换为字符串,因为它也是一个单元素数组,它的字符串表示形式是该单个元素的字符串表示形式:[“bar”]。

["bar"] is also an array with one element, which is a string, so the string representation of ["bar"] is just "bar".

[“bar”]也是一个带有一个元素的数组,它是一个字符串,因此[“bar”]的字符串表示只是“bar”。

What this comes down to is: [[["bar"]]].toString() === "bar"

这归结为:[[[“bar”]]]。toString()===“bar”

and foo[[[["bar"]]]] is the same as foo[[[["bar"]]].toString()].

和foo [[[[“bar”]]]]与foo [[[[“bar”]]]。toString()]相同。

You would also find that:

您还会发现:

foo[[[[1]],[2]]] === foo["1,2"]

because: [[[1]],[2]].toString() === "1,2".

因为:[[[1]],[2]]。toString()===“1,2”。

#2


6  

Let's see how foo[[[["bar"]]]] is evaluated, step-by step:

让我们看看如何评估foo [[[[“bar”]]]]的步骤:

  1. The outermost brackets in foo[...] denote a property accessor. The expression foo[[[["bar"]]]] thus translates to accessing a property of foo with name [[["bar"]]].

    foo [...]中最外面的括号表示属性访问器。表达式foo [[[[“bar”]]]]因此转换为访问名为[[[“bar”]]]的foo属性。

  2. According to the ECMA standard, the abstract operation ToPropertyKey(name) is then used to turn the name [[["bar"]]] into a property key value:

    根据ECMA标准,抽象操作ToPropertyKey(name)然后用于将名称[[[“bar”]]]转换为属性键值:

    A property key value is either an ECMAScript String value or a Symbol value.

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

    The name [[["bar"]]] is not of type Symbol and thus converted into a string. An array is converted to a string by joining all its string converted values:

    名称[[[“bar”]]]不是Symbol类型,因此转换为字符串。通过连接其所有字符串转换值,将数组转换为字符串:

    [[["bar"]]].toString() === "bar"
    
  3. Which finally means that our property key actually becomes "bar":

    这最终意味着我们的属性键实际上变成了“bar”:

    foo[[[["bar"]]]] === foo[[[["bar"]]].toString()] === foo["bar"]