An object's properties can be accessed through bracket notation by doing the following:
let obj = {a: "test"}
obj["a"]
However, I was not aware that the same object's property could also be accessed by doing:
let v = ["a"] // An array
obj[v]
or
obj[["a"]]
or
obj[[[[[[[[[["a"]]]]]]]]]]
Just wondering, why is that?
I stumbled on this behaviour after storing an array into a variable and mistakingly using the variable/array, rather than the first item of the array, to access an object's property and surprisingly... it didn't throw an error but returned the value.
All object keys are strings. When you use bracket notation foo[bar]
the variable you try to fetch will be converted to a string:
const bar = {
toString() {
return "hello";
}
}
const foo = {
hello: "world"
}
console.log(foo[bar]);
When arrays are converted to a string, join(",")
is implicitly called on them. And if an array has a single value, the result is the single value as a string:
const arr = ["hello"];
console.log(arr.toString());
console.log(String(arr));
console.log(arr.join(","));
If you have nested arrays, each with one item, you'd still get a single string out of the conversion, since join()
also converts all the members into strings, so with String([["hi"]])
you (roughly) get:
[["hi"]].join(",")
-> String(["hi"])
-> ["hi"].join(",")
-> String("hi")
So, if you supply an array as a key, it works, as long as you only have a single value in each array:
const foo = {
hello: "world"
};
const arr = [[["hello"]]];
console.log(foo[arr]);
console.log(foo[String(arr)]);
console.log(foo[arr.toString()]);
console.log(foo[arr.join(",")]);