let original = {name: 'Joel', favoriteFood: 'oranges', age: 26};
let happyBirthday = {...original, age: 27};
happyBirthday will be an object that is identical to original but with the age overwritten.
So that would result in an object like this:
{name: 'Joel', favoriteFood: 'oranges', age: 27} // Notice the age
Answer from Pedro Filipe on Stack Overflowlet original = {name: 'Joel', favoriteFood: 'oranges', age: 26};
let happyBirthday = {...original, age: 27};
happyBirthday will be an object that is identical to original but with the age overwritten.
So that would result in an object like this:
{name: 'Joel', favoriteFood: 'oranges', age: 27} // Notice the age
Objects cannot have duplicate keys. If you assign a key to an object when that object already has said key, or write an object initializer with duplicate keys, the prior value at that key will be overwritten:
const obj = {
foo: 'foo',
bar: 'bar',
};
obj.foo = 'new';
console.log(obj);
const obj = {
foo: 'foo',
bar: 'bar',
foo: 'new',
};
console.log(obj);
When using object spread, the same sort of thing is going on. If you add a key-value pair when a prior key already exists in the object initializer (by spread or otherwise), the prior value will be overwritten.
let happyBirthday = {...original, age: 27};
is very similar to
// Create a new object with all properties of `original`:
let happyBirthday = Object.assign({}, original);
// Assign to the `age` property of the new object:
happyBirthday.age = 27;
Spread operator with objects - javascript
Spread operator not working when doing array.map on an array of objects?
Difference between map() on a spread operator array or normal array?
Spread operator
There are a couple of things going on there:
Object spread syntax (it's not an operator) allows you to "spread" the values
nullandundefined. When you do, no properties are added to the object being created. (This is just likeObject.assign, which ignoresnullandundefinedin its argument list.)The
&&operator accepts two operands, evaluates the first, and if that value is falsy, takes that value as its result; it only evaluates the second operand and takes it as its result if the first value is truthy.
Taking those two things together, in the object literal, the ...(obj.size && { size: `${obj.size}cm` }) part works like this: if obj.size is undefined, it's basically ...undefined which doesn't add any properties to the object. But if obj.size is truthy, the second operand { size: `${obj.size}cm` } (an object literal) is evaluated, results in an object, and you end up with ...{ size: `${obj.size}cm` } which adds a size property to the object being created.
Note: If obj.size is 0, there will be no size property on the result, because 0 is falsy. So the author may well be incorrectly dropping size or weight with that solution:
function myFunction(obj) {
return {
fn: obj.fn,
ln: obj.ln,
...(obj.size && { size: `${obj.size}cm` }),
...(obj.weight && { weight: `${obj.weight}kg` }),
};
}
console.log(myFunction({fn: "fn", ln: "ln", size: 0}));
When obj.size is 0, you end up with ...0 in the object, which (in theory) creates a Number object (rather than primitive) from the primitive 0 then spreads its properties. It doesn't put any properties in the object because, by default, Number objects don't have any own, enumerable properties.
Now, if the problem is defined such that size and weight will never be 0, fair enough. But I would think carefully before generalizing that solution.
The lines with the spread operator should work! But they will just add values if obj.size resp. obj.weight are not undefined!
In this case they add the keys size, resp. weight to the object.
If obj.size=10, then:
{key1:value1, key2:value2 ,..., keyN:valueN, ...(obj.size && { size: `${obj.size}cm` })}
=> {key1:value1, key2:value2 ,..., keyN:valueN, ...(10 && { size: `${10}cm` })}
=> {key1:value1, key2:value2 ,..., keyN:valueN, ...({ size: `10 cm` })
=> {key1:value1, key2:value2 ,..., keyN:valueN, size: `10 cm`}
If obj.size=undefined, then:
{key1:value1, key2:value2 ,..., keyN:valueN,...(obj.size && { size: `${obj.size}cm` })}
=> {key1:value1, key2:value2 ,..., keyN:valueN,...(undefined )}
=> {key1:value1, key2:value2 ,..., keyN:valueN}