Why does javascript evaluate the following as true, given that object foo has a valid property bar?
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"]?
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:
> test = [[["bar"]]]
[Array[1]]
> foo["bar"] = 5
5
> foo[test]
5
What aspect of the language or parser is causing this behavior? Thanks!
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".
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"]].
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"] is also an array with one element, which is a string, so the string representation of ["bar"] is just "bar".
What this comes down to is: [[["bar"]]].toString() === "bar"
and foo[[[["bar"]]]] is the same as foo[[[["bar"]]].toString()].
You would also find that:
foo[[[[1]],[2]]] === foo["1,2"]
because: [[[1]],[2]].toString() === "1,2".
Let's see how foo[[[["bar"]]]] is evaluated, step-by step:
The outermost brackets in foo[...] denote a property
accessor. The expression foo[[[["bar"]]]] thus translates to
accessing a property of foo with name [[["bar"]]].
According to the ECMA standard, the abstract operation
ToPropertyKey(name) is then used to turn the name [[["bar"]]]
into a property key value:
A property key value is either an ECMAScript String value or a Symbol value.
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"]]].toString() === "bar"
Which finally means that our property key actually becomes "bar":
foo[[[["bar"]]]] === foo[[[["bar"]]].toString()] === foo["bar"]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With