On the JavaScript telegram (not my channel, but at the time of writing, it has almost 30,000 subscribers), there was a "challenge" quiz post with this snippet:
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const mergedObj = { ...obj1, ...obj2 };
console.log(mergedObj);
The channel then proceeded to ask "What is the output?":
{ a: 1, b: 2, c: 4 }
{ a: 1, b: 2, c: 3 }
{ a: 1, b: 3, c: 4 }
{ a: 1, c: 4 }
The correct answer was (of course?) "c" : { a: 1, b: 3, c: 4 }
But why?
Before we look it up, we could "learn-by-experimenting" and see if we can recognize a pattern. Let's try changing the code a bit:
const obj1 = { a: 1, b: 2, c: 0 };
const obj2 = { b: 3, c: 4 };
const mergedObj = { ...obj1, ...obj2 };
console.log(mergedObj);
The console will log { a: 1, b: 3, c: 4 }
From the last two examples, we can begin to see a pattern:
- When using the spread operator as above, JavaScript will take the value of the last object that had each property
- the
mergedObj
will takeobj1
's value ofa
- (
obj2
did not have a property nameda
)
- (
- the
mergedObj
will then takeobj2
's value of propertiesb
andc
- (the value of each property of the most recent object with each property)
- the
Exploring further
Let's explore a little further with more objects that have more properties:
const obj1 = { a: 21, b: 2, c: 0, d: -1, e: true, f: [1, 1, 1] };
const obj2 = { a: 1, b: -1, c: true, e: 0 }
const obj3 = { b: 3, c: 4, e: false, f: true };
const mergedObj = { ...obj1, ...obj2, ...obj3 };
console.log(mergedObj);
Could we guess what would log to the console?
Did we guess: { a: 1, b: 3, c: 4, d: -1, e: false, f: true }
?
Did we guess correctly? Of course we did!
a
appears last inobj2
so it's1
b
appears last inobj3
so it's3
c
appears last inobj3
so it's4
- d appears last in
obj1
so it's-1
e
appears last inobj3
so it'sfalse
e
appears last inobj3
so it'strue
Back it up with some other documentation?
So now, let's confirm our pattern recognition with some MDN: on the spread syntax article, under the heading "Overriding properties" it says:
"When one object is spread into another object, or when multiple objects are spread into one object, and properties with identical names are encountered, the property takes the last value assigned while remaining in the position it was originally set."
...and there we have it!
Summary
When we have multiple JavaScript objects:
- If we merge each object using the spread operator into a "merged object":
- The merged object takes all properties from all objects
- The final value of each property is "the value of each property of the most recent object with each property"!