Mike Mike - 5 months ago 22
Javascript Question

How does object[[["key"]]] evaluate to object["key"] in javascript?

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!

Answer

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".