10

Consider the following

var a = {foo: "bar"};

Equivalent to

var a = {};
a.foo = "bar";

Equivalent to

var a = {};
a['foo'] = "bar";

Equivalent to

var a = {}
var b = "foo";
a[b] = "bar";

Is it possible to do something like

var b = "foo";
var a = { [b]: "bar" };

Such that the result would be

// => {foo: "bar"}

Acceptable solutions are in JavaScript or CoffeeScript

Mulan
  • 129,518
  • 31
  • 228
  • 259

7 Answers7

6

No.

There is no way to do it using object literal notation.


UPDATE: According to the ECMAScript standard 6.0 you are now able to do the following:

var b = 'foo';
var a = { [b]: 'bar' };

console.log( a.foo );  // "bar"

However, this solution won't work in old browsers, which do not support ES6.

VisioN
  • 143,310
  • 32
  • 282
  • 281
  • 3
    Of course, then there's the better-left-unmentioned function that can do it at the expense of invoking the compiler each time it's run. – John Dvorak Dec 21 '12 at 22:06
5

ES6 supports computed properties.

// code from my original question now works in ES6 !
let b = "foo";
let a = { [b]: "bar" };

a.foo; //=> "bar"

Any expression can be used within the [] to define the property name

let a = {
  [(xs => xs.join(''))(['f','o','o'])]: 'bar'
};

a.foo; //=> "bar"

If you need to rely on this behavior in an ES5 world, you can lean on the very capable babel.js to transpile your ES6 code to ES5-compatible code.

Mulan
  • 129,518
  • 31
  • 228
  • 259
4

JSON parse allows you to convert a JSON string into an object:

JSON.parse('{"'+dynamicProperty+'":"bar"}');

This is not exactly an object litteral, but if your objective is to enter your property name as a variable it works.

Christophe
  • 27,383
  • 28
  • 97
  • 140
  • How the heck did I forget about this. Good thinking. I think you want a `:`, not a `=` though, right? – Ian Dec 21 '12 at 22:30
  • 1
    A more accurate version (to account for double quotes and other special characters in property name) would be `JSON.parse('{'+JSON.stringify(dynamicProperty)+':"bar"}')`, but at that point why not just write it in two lines (pre ES6)? (Don't mind my time machine) – riv May 22 '18 at 01:24
4

As others have said, no, there's currently no syntax for interpolated key strings in object literals in CoffeeScript; but it seems at some point this feature existed! In these GitHub issues there's some discussion about it: #786 and #1731.

It's implemented in Coco and LiveScript as:

b = 'foo'
a = {"#{b}": 'baz'}

# Or..
a = {(b): 'bar'}
epidemian
  • 18,817
  • 3
  • 62
  • 71
1

As of CoffeeScript version 1.9.1 this works:

b = "foo"
a = "#{b}": "bar"

It compiles to:

var a, b, obj;

b = "foo";

a = (
  obj = {},
  obj["" + b] = "bar",
  obj
);

Try it.

Sukima
  • 9,965
  • 3
  • 46
  • 60
0

JavaScript

var a, b;
(a = {})[b = 'foo'] = 'bar';

CoffeeScript

(a = {})[b = 'foo'] = 'bar'
Casey Foster
  • 5,982
  • 2
  • 27
  • 27
-1

To answer your question, this is the only way that I know of. It uses eval. But beware, eval is evil!

var b = "foo";
var a = eval('({ ' + b + ': ' + '"bar"' + ' })');

This is an ugly solution. To play it safe you should not rely on this. Don't use it!

David G
  • 94,763
  • 41
  • 167
  • 253
  • Why is it evil in this case? I don't understand why people think `eval` is evil 100%... – Ian Dec 21 '12 at 22:24
  • Since people don't like `eval` there is another way: `new Function("return {" + b + ": 'bar'}")()`. – VisioN Dec 21 '12 at 22:24
  • @Ian Because there are very little if not no cases where `eval` is sufficiently applicable. `eval` in this case isn't even is a good solution, it's a hack. – David G Dec 21 '12 at 22:26
  • @David That doesn't make it evil. I could understand an argument that it's "unnecessary". When people say "evil", I bet they're thinking "DANGEROUS" because that's what people on SO immediately claim when they see it. I agree it's not a "solution", but since when are hacks not solutions? In this case, it's not like it goes out and does a bunch of extra things at a **high** expense of performance. Isn't this a/the way JSON is parsed if `JSON` is not available? You didn't see people looping through all characters of a JSON string, parsing it and building an object literal that way – Ian Dec 21 '12 at 22:34