Home > Net >  Why object merges properties but array does not merges values
Why object merges properties but array does not merges values

Time:12-09

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 of b changes based on the latest object having b.

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 how Object.assign is supposed to work. The keys in this case are simply what we call "index" in an array. This is why when you do array[index] it returns the value, it's the same as object[key] that returns a value. The Object.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]
  • Related