442

First off, I'm using Cheerio for some DOM access and parsing with Node.js. Good times.

Heres the situation:

I have a function that I need to create an object. That object uses variables for both its keys and values, and then return that single object. Example:

stuff = function (thing, callback) {
  var inputs  = $('div.quantity > input').map(function(){
    var key   = this.attr('name')
     ,  value = this.attr('value');

     return { key : value }
  }) 

  callback(null, inputs);
}

It outputs this:

[ { key: '1' }, { key: '1' } ]

(.map() returns an array of objects fyi)

I need key to actually be the string from this.attr('name').

Whats the best way to assign a string as a key in Javascript, considering what I'm trying to do?

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
JDillon522
  • 19,046
  • 15
  • 47
  • 81

2 Answers2

1166

In the new ES2015 standard for JavaScript (formerly called ES6), objects can be created with computed keys: Object Initializer spec.

The syntax is:

var obj = {
  [myKey]: value,
}

If applied to the OP's scenario, it would turn into:

stuff = function (thing, callback) {
  var inputs  = $('div.quantity > input').map(function(){
    return {
      [this.attr('name')]: this.attr('value'),
    };
  }) 

  callback(null, inputs);
}

Note: A transpiler is still required for browser compatiblity.

Using Babel or Google's traceur, it is possible to use this syntax today.


In earlier JavaScript specifications (ES5 and below), the key in an object literal is always interpreted literally, as a string.

To use a "dynamic" key, you have to use bracket notation:

var obj = {};
obj[myKey] = value;

In your case:

stuff = function (thing, callback) {
  var inputs  = $('div.quantity > input').map(function(){
    var key   = this.attr('name')
     ,  value = this.attr('value')
     ,  ret   = {};

     ret[key] = value;
     return ret;
  }) 

  callback(null, inputs);
}
user2864740
  • 60,010
  • 15
  • 145
  • 220
Renato Zannon
  • 28,805
  • 6
  • 38
  • 42
  • 6
    Great edit. Now if ES6 can just be officially released we might have a shot at world peace! :) – JDillon522 Sep 12 '14 at 18:44
  • You can use Computed Property Keys now if you're willing to use a transpiler like Babel. Example: https://babeljs.io/repl/#?experimental=true&evaluate=true&loose=false&spec=false&code=const%20NAME%20%3D%20'NAME'%3B%0A%0Aconsole.log(%7B%0A%20%20%5B'full'%20%2B%20NAME%5D%3A%20'Mike%20Smith'%0A%7D)%3B – Johnny Oshika Oct 13 '15 at 17:27
  • Great update about *computed keys*. That's what I'm looking for these days. I just wonder how did you know about this "magic". Reading the (so long) ES2015 spec document? – haotang Feb 01 '16 at 13:08
  • 1
    For computed keys, I am getting a syntax error when using gulp minify task. Any body faced this? and any solution? – Vamshi Vangapally Apr 18 '16 at 20:08
  • can this also work for nested Objects suppose i have a nested object can i use var obj ={ [dynamic key][dynamic key]=someValue } – Mahi Tej Gvp Oct 24 '17 at 09:43
  • worked for me, had to think how to search for that question – Baqer Naqvi Jan 14 '21 at 09:56
  • Any solution for TypeScript? – s3c Nov 24 '22 at 07:32
  • worked for me thanks – Daniel_Ranjbar Jul 17 '23 at 15:29
72

You can't define an object literal with a dynamic key. Do this :

var o = {};
o[key] = value;
return o;

There's no shortcut (edit: there's one now, with ES6, see the other answer).

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • 9
    I think in es6 you can now do this: var propname = 'thing' {[propname]:5} -> {thing:5} See this for more : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer – Dtipson Nov 13 '15 at 20:57