In order to use a variable as an object's key, ES6 introduced something called "computed property names", where you add brackets to your variable and it gets replaced with its value:

let theKey = "color";
let theValue = "red";

// {"theKey": "red"}
console.log( { theKey: theValue } );

// {"color": "red"}
console.log( { [theKey]: theValue } );

In fact, you can put anything inside the brackets and it will evaluate as an expression:

// {"color1518560798108": "red"}
console.log( { [ theKey + (new Date).valueOf() ]: theValue } );
Final thoughts

I don't have a problem with Javascript being dynamically typed or anything like that. I do, however, have strong feelings against supporting multiple ways of doing the exact same thing for no apparent reason. Why is {color:"red"} the same as {"color":"red"}? or {'color':'red'} for that matter? It seems to me that since object keys are strings, then keys should be written as strings and not this magic conversion logic that doesn't even solve all cases.

Consider {a:"A", b:"B", c-property:"C"}, or console.log(a.b.c-property.d);, neither of which work. The solution for these is:

{
  a: "A",
  b: "B",
  "c-property": "C" // Inconsistent syntax, not to mention the trailing comma issue which makes this extra ugly
}

console.log(a.b["c-property"].d); // You're tearing me apart, Javascript!

The point is, "computed property names" should've always worked without needing this weird bracket syntax; keys should've always been evaluated as expressions.

Previous on Javascript