JavaScript engines typically put a cap on the number of arguments you can pass to a method before they throw an error, for example, the below throws an error in Chrome:
const arr = Array(150000).fill(0);
const arr2 = [];
arr2.push(...arr);
Whereas when using .concat(), you'll only be passing the one array to the method, so you don't get the error:
const arr = Array(150000).fill(0);
const arr2 = [];
const res = arr2.concat(arr);
// res is an array with 150000 `0`s
Additionally, with .push() + ..., you're effectively doing two iterations over your iterable/array, one for unpacking its contents as arguments to the .push() method, and then another for one done internally by the .push() method itself to iterate through each of the arguments and append it to the target array.
Another noticeable difference is in what both methods return, .concat() will return a new array and won't modify the target, which can be useful in methods such as .map() or .reduce() where you need to produce a new array without mutating the original. Whereas .push() will return the length of the updated array and will modify the target, so that is another difference to consider.
As pointed out by @T.J. Crowder, the iterator of arrays which is invoked when using the spread syntax ... does not preserve blanks in sparse arrays, instead it unpacks them as undefined values, meaning that if the array you're specifying is sparse when using .push() + ... you'll get undefined for the blanks, whereas the blanks will be preserved when using .concat() directly:
const arr = Array(3); // this is a sparse array, [empty × 3], not to be confused with [undefined, undefined, undefined]
const arr2 = [];
arr2.push(...arr); // Here `...` becomes: arr2.push(undefined, undefined, undefined);
console.log(arr2); // [undefined, undefined, undefined]
const arr3 = [];
console.log(arr3.concat(arr)); // Retains empties: [empty × 3]
See browser console for results
Answer from Nick Parsons on Stack Overflowjavascript - How to join / combine two arrays to concatenate into one array? - Stack Overflow
Better performing alternative to Array.unshift
Logical concatenation for large arrays
JavaScript String method: Split, Concat, and Join
Videos
JavaScript engines typically put a cap on the number of arguments you can pass to a method before they throw an error, for example, the below throws an error in Chrome:
const arr = Array(150000).fill(0);
const arr2 = [];
arr2.push(...arr);
Whereas when using .concat(), you'll only be passing the one array to the method, so you don't get the error:
const arr = Array(150000).fill(0);
const arr2 = [];
const res = arr2.concat(arr);
// res is an array with 150000 `0`s
Additionally, with .push() + ..., you're effectively doing two iterations over your iterable/array, one for unpacking its contents as arguments to the .push() method, and then another for one done internally by the .push() method itself to iterate through each of the arguments and append it to the target array.
Another noticeable difference is in what both methods return, .concat() will return a new array and won't modify the target, which can be useful in methods such as .map() or .reduce() where you need to produce a new array without mutating the original. Whereas .push() will return the length of the updated array and will modify the target, so that is another difference to consider.
As pointed out by @T.J. Crowder, the iterator of arrays which is invoked when using the spread syntax ... does not preserve blanks in sparse arrays, instead it unpacks them as undefined values, meaning that if the array you're specifying is sparse when using .push() + ... you'll get undefined for the blanks, whereas the blanks will be preserved when using .concat() directly:
const arr = Array(3); // this is a sparse array, [empty × 3], not to be confused with [undefined, undefined, undefined]
const arr2 = [];
arr2.push(...arr); // Here `...` becomes: arr2.push(undefined, undefined, undefined);
console.log(arr2); // [undefined, undefined, undefined]
const arr3 = [];
console.log(arr3.concat(arr)); // Retains empties: [empty × 3]
See browser console for results
I don't understand if you want to add an Array into another or just make one Array made of two Arrays.
In the last case this is a short way to concatenate Arrays too by using spread syntax:
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combinedArray = [...arr1, ...arr2];
console.log(combinedArray);
Note:
If you need to preserve the original arrays, this code above is suitable, like the concat() method.
The push() method will modify your initial Array.
Copyvar a = ['a','b','c'];
var b = ['d','e','f'];
var c = a.concat(b); //c is now an an array with: ['a','b','c','d','e','f']
console.log( c[3] ); //c[3] will be 'd'
Using ES6 JavaScript - spread syntax:
Copyconst a = ['a', 'b', 'c'];
const b = ['d', 'e', 'f'];
const c = [...a, ...b]; // c = ['a', 'b', 'c', 'd', 'e', 'f']
It is also the fastest way to concatenate arrays in JavaScript today.
However, when dealing with large arrays, it is more efficient to chain them (concatenate logically):
Copyfunction chainArrays<T>(...arr: T[][]): Iterable<T> {
return {
[Symbol.iterator](): Iterator<T> {
let i = 0, k = -1, a: T[] = [];
return {
next(): IteratorResult<T> {
while (i === a.length) {
if (++k === arr.length) {
return {done: true, value: undefined};
}
a = arr[k];
i = 0;
}
return {value: a[i++], done: false};
}
};
}
}
}
// usage example:
const a = [1, 2];
const b = [3, 4];
const c = [5, 6];
for (const value of chainArrays(a, b, c)) {
console.log(value); //=> 1, 2, 3, 4, 5, 6
}
Above, we have to use while(i === a.length) logic in order to skip all empty arrays, while also for jumping to the next array at the end of the current one.
A generator approach for the same is much simpler, while also slower:
Copyfunction* chainArrays<T>(...arr: T[][]) {
for (const i of arr)
for (const v of i)
yield v;
}
// test:
for (const value of chainArrays(a, b, c)) {
console.log(value); //=> 1, 2, 3, 4, 5, 6
}
Internally, a generator is translated into a more verbose IterableIterator, which used to perform slower than a manual iterable, but JavaScript engines keep improving, so it's for you to test it out in your environment ;) But I tested it under Node v20, and on average the manual iterable performs 2 times faster than our generator here.
For a complete TypeScript implementation (including reversed logic), see this gist, or this repo.