Search code examples
javascriptobjectsyntaxlanguage-specifications

Using strings when specifying a key in an object's key-value pair


When specifying a key in an object's key-value pair (using the notation below) the interpreter (apparently) allows the use of strings:

var x = { 'color': '#fff' };

However specifying a key dinamically using a function (that returns a string) is not allowed:

function s()
{
    return 'color';
}

var x = { s(): '#fff' };

I guess strings, when using that notation, must be static values.

However I cannot find JavaScript language specifications regarding that...


Solution

  • According to this MDN article (I highlight with bold):

    The syntax for an object using an object initializer is:

    var obj = { property_1:   value_1,   // property_# may be an identifier...
                2:            value_2,   // or a number...
                // ...,
                "property n": value_n }; // or a string
    

    where obj is the name of the new object, each property_i is an identifier (either a name, a number, or a string literal), and each value_i is an expression whose value is assigned to the property_i.

    So in this literal notation it is not allowed to evaluate expressions, e.g. via function calls to determine the property identifiers.

    In the ECMAScript Language Specification it is more formally put:

    PropertyName:

    • IdentifierName
    • StringLiteral
    • NumericLiteral

    ECMAScript 2015

    With ECMAScript 2015 more becomes possible as explained in this MDN article:

    Starting with ECMAScript 2015, the object initializer syntax also supports computed property names. That allows you to put an expression in brackets [ ], that will be computed as the property name.

    // Computed property names (ES6)
    var i = 0;
    var a = {
      ["foo" + ++i]: i,
      ["foo" + ++i]: i,
      ["foo" + ++i]: i
    };
    

    The formal definition in the ECMAScript 2015 Language Specification has:

    PropertyName:

    • LiteralPropertyName
    • ComputedPropertyName

    ComputedPropertyName:

    • [ AssignmentExpression ]

    So with ES6 you would rewrite your example like this:

    function s()
    {
        return 'color';
    }
    
    var x = { [s()]: '#fff' };