JS - Create object shorthand
Asked Answered
P

5

5

Take the below object:

var value = 'bar';
var obj = { foo: value }
// -> Object { foo="bar" }

Supposing the key was also a variable, one could go:

var key = 'foo', value = 'bar';
var obj = {}
obj[key] = value;
// -> Object { foo="bar" }

Now, I want to do this in one line (shorthand). So I tried:

var obj = {}[key] = value; // or,
var obj = ({})[key] = value; // or,
var obj = new Object()[key] = value;
// -> "bar"

This oddly produces a String instead of an Object.

Is there any way to do this shorthand?

Pola answered 16/12, 2014 at 22:20 Comment(7)
No, there isn't, and why would there be !Rego
Same reason I would use {} instead of new Object(). It's just cleaner in some instances.Pola
how var obj = new Object()[key] = value; is better than var obj = {}; obj[key] = value;?Disembody
ES6 only obj = {[key]: value}Initiate
None of your attempts are cleaner than simply typing it out on two lines...Eclogue
@meagar I agree 100%, I hope the OP doesn't start using one of the suggested answers that also aren't very readableConspecific
It's sad that the only correct answer was downvoted and deleted. Outside of ES6, there is no shorthand for this. All the answers are horrible, and not a "shorthand" by any sane definition. Do you seriously think var obj = (function(o) {o[key]=value; return o})({}); is a good shorthand for var obj = {}; obj[key] = value?Eclogue
M
6

ECMAScript 6 will allow you to do

var obj = {
    [key]: value
};

Browser support is not great yet, but transpilers such as 6to5 allow you to use this notation today!

Myrmeco answered 16/12, 2014 at 22:27 Comment(1)
Looking forward to it :)Pola
F
6

You can, or almost can. If you put the creation of the object, and its assignment to obj in parentheses, you can set a property of the result of that expression:

var obj, key='foo', value = 'bar';
(obj = {})[key] = value;

alert(obj);  // [object Object]
alert(obj.foo);  // bar

The var keyword cannot be included in that expression within parentheses, so either you will have to declare obj before (like I did), or not declare it at all and accept that it will be in global scope.

Felecia answered 16/12, 2014 at 22:24 Comment(10)
This is more what I was looking for.Pola
Nice, but it relies on assignment returning the assigned value, I don't think I would ever use it in production, but it's clever golfing.Rego
Can't get any cleaner than that.Hambletonian
Isn't this two lines?Conspecific
It does rely on assignments returning the assigned value, but I don't think that's a "but". This fenomenon is used a lot in production code, although maybe not in a case like this. But what about code like while (element = element.getNextSibling()) { doSomethingWith(element); }?Felecia
Um, I just tried this in a browser console, and it also returned a string like in my example. Anyone else test it?Pola
That's because in my snippet, I alerted the foo property of the object instead of the object itself. I wanted to show that it is an actual object and that the assignment of the property also worked. I changed it to two alerts now. Tested and works in IE 11 and Chrome 39.Felecia
@dc2 This isn't cleaner, if anything this is just obfuscating your code! Don't use this, or any of the answers here. Slamming a bunch of things onto one line is not a desirable goal in and of itself. Your need to focus on writing readable code, not writing short code. All of these answers are technically correct, but universally horrible. Any developer reviewing your code is going to tell you to fix any such instances. If I ever encountered (obj = {})[key] = value; I would immediately strip it out, git blame it, and tell the person responsible never to do it again.Eclogue
@meager I agree. For academic purposes it is nice to solve such a puzzle and it will teach you valuable lessons about how JavaScript evaluates complex expressions. Whether to use it in production is up to dc2. I admit, I wouldn't use this in production either and just use more lines of code until ECMA6 would be available in every browser I would like to support.Felecia
@meagar tracking :) don't worry - there won't be any cataclysmic upheavals due to answers posted here. I was simply curious.Pola
M
6

ECMAScript 6 will allow you to do

var obj = {
    [key]: value
};

Browser support is not great yet, but transpilers such as 6to5 allow you to use this notation today!

Myrmeco answered 16/12, 2014 at 22:27 Comment(1)
Looking forward to it :)Pola
R
3

Depends on what you call a one-liner, with some code golf you can do

var obj = (function(o) {o[key]=value; return o})({});

it think that's the shortest you'll get it ?

Rego answered 16/12, 2014 at 22:24 Comment(5)
@Hristo That is an empty object being passed into the anonymous function that is immediately executedConspecific
I'm still trying to understand... The function expression is executed immediately and returns an object. Intuitively I suppose that the empty object {} in the parentheses at the end ({}) will be prozessed as parameter for the function(o). Is that correct? I just don't get the relation of ({}) on the right and the anonymous function expression (function(o){...}) on the left?!Olwen
@Olwen - Maybe it's clearer if you break it up -> jsfiddle.net/puk7kafyRego
No, the part about the empty object was clear... but a function definition like function(){}() I can't understand... Normally it shall be defined just like function(){} ... Please give me a reference for the second pair of parentheses - what do they and if this definition can be used in some other context?Olwen
@Olwen If you name the function and break it up, it should clarify that the empty object is being passed into the function function create(o) {o[key]=value; return o}; Now use it like var obj = create({})' Then if you work your way back and inline the create function, it should see what is happening, you just need to realize that there are parentheses around the function.Conspecific
W
3

Something like that is coming in ECMAScript 6:

With ECMAScript 6, there is a shorter notation available to achieve the same:

var a = "foo", 
    b = 42, 
    c = {};

// Shorthand property names (ES6) 
var o = { a, b, c };

So you could create your object with the following code

var foo = 'bar';
var obj = {foo};
Withhold answered 16/12, 2014 at 22:26 Comment(0)
C
0

No shorthand in ECMAScript 5 (the current version), but you can make a method

function createObject(key, value /*, key, value, ... */ ) {
    var object = {};
    for (var i = 0; i < arguments.length; i = i + 2) {
        object[arguments[i]] = arguments[i+1];
    }
    return object;
}

Then you can call it like this

var obj = createObject(key, value, 'anotherKey', 'anotherVal');
Conspecific answered 16/12, 2014 at 22:25 Comment(2)
Isn't this eight lines? ;-)Felecia
One line every time you call it.Conspecific

© 2022 - 2024 — McMap. All rights reserved.