Can someone tell why object merges values but array does not
See the code block below:
const a = {'a': 1, 'b': 2}
const b = {'b': 4, 'c': 3}
console.log({...a, ...b})
This Outputs
{ a: 1, b: 4, c: 3 }
But when I use the code below:
const c = [1,2]
const d = [2,3]
console.log([...c, ...d])
This outputs
[ 1, 2, 2, 3 ]
CodePudding user response:
Why object merges properties...
It doesn't merge properties, it merges objects. Notice the value of b
in your result: It's 4
(the value from the b
object), not some merged value of 2
(from the a
object) and 4
(from the b
object). Each property from each source object is just copied into the target object, the properties themselves are not merged together.
But fundamentally, object property spread and iterable spread are just completely different things with different purposes and different semantics, because objects and arrays are different beasts (at least conceptually; arrays actually are objects in JavaScript). Properties have names which are an intrinsic part of the property. Array elements just have indexes, and it's normal for values to be moved around an array (moved to different indexes). The two different definitions of spread are each useful for the data type they're defined for.
If you want to treat an array like an object, though, you can since arrays are objects in JavaScript. (Although in this case it isn't useful.) Here's an example (I've changed c
's element values so it's clear what's coming from where):
const c = ["a", "b"];
const d = [2, 3];
console.log(Object.assign([], c, d));
In that case, since d
has values for both indexes 0
and 1
, none of c
's elements are in the result. But:
const c = ["a", "b", "c", "d", "e"];
const d = [2, 3];
console.log(Object.assign([], c, d));
CodePudding user response:
Short answer
- When using the spread operator, Regular Objects are ASSIGNED.
- When using the spread operator, Arrays are CONCATENATED.
I believe the source of your confusion is that every array in JavaScript is just an object belonging to the Array constructor. So why doesn't joining two or more arrays with the spread operator work the same way as objects do?
Let's analyze what is happening in case of the Object
const a = {'a': 1, 'b': 2};
const b = {'b': 4, 'c': 3};
console.log({...a, ...b}); // Output: { a: 1, b: 4, c: 3 }
console.log(Object.assign({}, a, b)); // Output: { a: 1, b: 4, c: 3 }
console.log({...b, ...a}); // Output: { a: 1, b: 2, c: 3 }
console.log(Object.assign({}, b, a)); // Output: { a: 1, b: 2, c: 3 }
- An object is a data structure holding
key:value
pairs. - Object assignment overwrites the keys with the latest values.
- The key
b
occurs in more than one object and is overwritten with it's latest value. As you can see, if you change the order of the objects spread/assigned, the resulting value of the value ofb
changes based on the latest object havingb
.
Now let's come to the Array.
const c = [1,2];
const d = [2,3];
console.log([...c, ...d]); // Output: [ 1, 2, 2, 3 ]
console.log(c.concat(d)); // Output: [ 1, 2, 2, 3 ]
console.log(Object.assign({}, c, d)); // Output: { '0': 2, '1': 3 }
console.log(Object.values(Object.assign({}, c, d))); // Output: [ 2, 3 ]
- An array is an object created with the Array constructor which outputs the array as a collection of the values assigned to its keys.
- Array concatenation simply joins the arrays.
- As you can see above,
Object.assign
still works on an array because the array is technically an object and it behaves exactly howObject.assign
is supposed to work. The keys in this case are simply what we call "index" in an array. This is why when you doarray[index]
it returns the value, it's the same asobject[key]
that returns a value. TheObject.assign
replaces the keys/index with the latest values.
Conclusion:
Thus, the difference is how the spread operator works for objects and arrays.
- In Objects, spread does
Object.assign
. - In Arrays, spread does Array concatenation =>
arrayA.concat(arrayB, arrayC, ...)
Bonus: Set
However, if you want the array to return only unique values, you have to use the Set data structure.
const c = [1,2];
const d = [2,3];
console.log([...new Set([...c, ...d])]); // Output: [1, 2, 3]
console.log(Array.from(new Set(a.concat(b)))); // Output: [1, 2, 3]