DEV Community

Andrey Smolko
Andrey Smolko

Posted on

4 1 1 1 1

Merge array-like objects by Array.prototype.concat()

Let's dive into the Array.prototype.concat() method in JavaScript. This handy method helps you merge arrays, creating a new array with elements from the arrays you provide. Here's a quick example:

const arr0= [], arr1 = [1,2], arr2 = [3,4];
const resultArray = arr0.concat(arr1, arr2);
// [1,2,3,4]
Enter fullscreen mode Exit fullscreen mode

Now, let's switch things up and try to concatenate some array-like objects:

const arr0 = [];
const arr1 = {0:1, 1:2, length:2};
const arr2 = {0:3, 1:4, length:2};
const resultArray = arr0.concat(arr1, arr2);
// [{...}, {...}]
Enter fullscreen mode Exit fullscreen mode

When you use array-like objects, Array.prototype.concat() doesn't flatten them like it does with arrays. Instead, it treats each array-like object as a single element.

So, is there a way to force Array.prototype.concat() to flatten array-like objects too? Sounds like a challenge for the JavaScript geeks! Let's figure it out together.

Array.prototype.concat() description from ECMAScript specification:

Image description

Let's pay attention to step5.a. There is a boolean variable spreadable which defines how Array.prototype.concat() treats its arguments. If spreadable is false (step 5.c) then an argument is added in resulting array as it is without been flatten. But if spreadable is true (step 5.b) then the argument can be flattened!

Function IsConcatSpreadable defines value of spreadable variable:

  1. If O is not an Object, return false.
  2. Let spreadable be ? Get(O, @@isConcatSpreadable).
  3. If spreadable is not undefined, return ToBoolean(spreadable).
  4. Return ? IsArray(O).

In step 2 - @@isConcatSpreadable is just a specification name of build-in Symbol Symbol.isConcatSpreadable.
The function IsConcatSpreadable returns true in 2 two cases: either the object is an array or it has the property with the name Symbol.isConcatSpreadable and the property value is not falsy.

This looks exactly like what we need! Let's add Symbol.isConcatSpreadable in array-liked objects we tried to concatenate:

const arr0 = [];
const arr1 = {0:1, 1:2, length:2, [Symbol.isConcatSpreadable]:true};
const arr2 = {0:3, 1:4, length:2, [Symbol.isConcatSpreadable]:true};
const resultArray = arr0.concat(arr1, arr2);
// [1,2,3,4] 
Enter fullscreen mode Exit fullscreen mode

Solved! Now Array.prototype.concat() flattens our array-like objects just like it does with regular arrays.

P.S. Symbol.isConcatSpreadable is used exclusively by the Array.prototype.concat() method. No other build-in methods uses it.

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay