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:
So with ES6 you would rewrite your example like this:
function s()
{
return 'color';
}
var x = { [s()]: '#fff' };