In JavaScript, how to conditionally add a member to an object?
Solution 1:
I think @InspiredJW did it with ES5, and as @trincot pointed out, using es6 is a better approach. But we can add a bit more sugar, by using the spread operator, and logical AND short circuit evaluation:
const a = {
...(someCondition && {b: 5})
}
Solution 2:
const obj = {
...(condition) && {someprop: propvalue},
...otherprops
}
Live Demo:
const obj = {
...(true) && {someprop: 42},
...(false) && {nonprop: "foo"},
...({}) && {tricky: "hello"},
}
console.log(obj);
Solution 3:
In pure Javascript, I cannot think of anything more idiomatic than your first code snippet.
If, however, using the jQuery library is not out of the question, then $.extend() should meet your requirements because, as the documentation says:
Undefined properties are not copied.
Therefore, you can write:
var a = $.extend({}, {
b: conditionB ? 5 : undefined,
c: conditionC ? 5 : undefined,
// and so on...
});
And obtain the results you expect (if conditionB
is false
, then b
will not exist in a
).
Solution 4:
With EcmaScript2015 you can use Object.assign
:
Object.assign(a, conditionB ? { b: 1 } : null,
conditionC ? { c: 2 } : null,
conditionD ? { d: 3 } : null);
var a, conditionB, conditionC, conditionD;
conditionC = true;
a = {};
Object.assign(a, conditionB ? { b: 1 } : null,
conditionC ? { c: 2 } : null,
conditionD ? { d: 3 } : null);
console.log(a);
Some remarks:
-
Object.assign
modifies the first argument in-place, but it also returns the updated object: so you can use this method in a bigger expression that further manipulates the object. - Instead of
null
you could passundefined
or{}
, with the same result. You could even provide0
instead, because primitive values are wrapped, andNumber
has no own enumerable properties.
Even more concise
Taking the second point further, you could shorten it as follows (as @Jamie has pointed out), as falsy values have no own enumerable properties (false
, 0
, NaN
, null
, undefined
, ''
, except document.all
):
Object.assign(a, conditionB && { b: 1 },
conditionC && { c: 2 },
conditionD && { d: 3 });
var a, conditionB, conditionC, conditionD;
conditionC = "this is truthy";
conditionD = NaN; // falsy
a = {};
Object.assign(a, conditionB && { b: 1 },
conditionC && { c: 2 },
conditionD && { d: 3 });
console.log(a);