Search code examples
javascriptarraysaccessornotation

Accessing object property through bracket notation regardless of the number of brackets


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.


Solution

  • 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(",")]);