One option is to use reduce:

let arrs = [[1, 2], [3, 4], [5, 6]];
arrs.reduce((a, b) => [...a, ...b], []);

Of course, this is a slow solution (quadratic time). Alternatively, if you can use Lodash, _.flatten does exactly what you want, and does it more efficiently (linear time).

EDIT

Or, adapted from Xotic750's comment below,

[].concat(...arrs);

Which should be efficient (linear time).

Answer from Brian McCutchon on Stack Overflow
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ how-to-use-spread-operator-to-join-two-or-more-arrays-in-javascript
How to use spread operator to join two or more arrays in JavaScript?
We can do merging in JavaScript in multiple ways. To combine two or more arrays, you can either use the functional method [].concat(arr1, arr2) or the spread operator [...arr1,...arr2]. The merging outcome is kept in a new array, making these methods immutable.
๐ŸŒ
MDN Web Docs
developer.mozilla.org โ€บ en-US โ€บ docs โ€บ Web โ€บ JavaScript โ€บ Reference โ€บ Operators โ€บ Spread_syntax
Spread syntax (...) - JavaScript | MDN
Spread syntax looks exactly like rest syntax. In a way, spread syntax is the opposite of rest syntax. Spread syntax "expands" an array into its elements, while rest syntax collects multiple elements and "condenses" them into a single element.
๐ŸŒ
GitHub
gist.github.com โ€บ yesvods โ€บ 51af798dd1e7058625f4
Merge Arrays in one with ES6 Array spread ยท GitHub
@basilbattikhi First of all if you are trying to merge two arrays, the result will be an array(obvious). Try this, const arrayOne = [{ a: "a" }, { b: "b" }, { c: "c" }]; const arrayTwo = [{ d: "d" }, { e: "e" }, { f: "f" }]; const arrayMerge = [ ...arrayOne, ...arrayTwo ]; console.log(arrayMerge); ... I've noticed a quirk behavior with spread for flattening an array of arrays.
๐ŸŒ
freeCodeCamp
freecodecamp.org โ€บ news โ€บ how-to-merge-arrays-in-javascript-array-concatenation-in-js
How to Merge Arrays in JavaScript โ€“ Array Concatenation in JS
November 28, 2022 - In the merged array here, we first spread array2, then array3, and lastly, array1. You can learn more about this operator in this article: Spread Operator Simplified.
๐ŸŒ
MDN Web Docs
developer.mozilla.org โ€บ en-US โ€บ docs โ€บ Web โ€บ JavaScript โ€บ Reference โ€บ Global_Objects โ€บ Array โ€บ concat
Array.prototype.concat() - JavaScript | MDN
The this value is treated in the same way as the other arguments (except it will be converted to an object first), which means plain objects will be directly prepended to the resulting array, while array-like objects with truthy [Symbol.isConcatSpreadable] will be spread into the resulting array.
๐ŸŒ
egghead.io
egghead.io โ€บ lessons โ€บ javascript-merge-arrays-using-the-spread-operator
Create a Custom Type Based of an Object with Typescript keyof Operator | egghead.io
Merge Arrays using the Spread Operator ยท 25s ยท 5 ยท Flatten a Nested Array in JavaScript with Array.prototype.flat ยท 50s ยท 6 ยท Merge Objects with JavaScript's Spread Operator ยท 25s ยท 7 ยท For...in Loop vs. For...of Loop ยท 1m 37s ยท 8 ยท Array.prototype.flatMap from ES2019 ยท
Published ย  July 16, 2019
Find elsewhere
๐ŸŒ
SamanthaMing
samanthaming.com โ€บ tidbits โ€บ 14-combine-multiple-arrays-using-spread
Combine Multiple Arrays Using Spread | SamanthaMing.com
Instead of using concat() to concatenate arrays, try using the spread syntax to combine multiple arrays into one flattened array๐Ÿ‘ ยท let veggie = ['๐Ÿ…', '๐Ÿฅ‘']; let meat = ['๐Ÿฅ“']; // Old Way let sandwich = veggie.concat(meat, '๐Ÿž'); ...
๐ŸŒ
SamanthaMing
samanthaming.com โ€บ tidbits โ€บ 49-2-ways-to-merge-arrays
2 Ways to Merge Arrays in JavaScript | SamanthaMing.com
Here are 2 ways to combine your arrays and return a NEW array. I like using the Spread operator. But if you need older browser support, you should use Concat. // 2 Ways to Merge Arrays const cars = ['๐Ÿš—', '๐Ÿš™']; const trucks = ['๐Ÿšš', '๐Ÿš›']; // Method 1: Concat const combined1 = [].concat(cars, trucks); // Method 2: Spread const combined2 = [...cars, ...trucks]; // Result // [ '๐Ÿš—', '๐Ÿš™', '๐Ÿšš', '๐Ÿš›' ]
๐ŸŒ
SamanthaMing
samanthaming.com โ€บ tidbits โ€บ 92-6-use-cases-of-spread-with-array
6 Use Case of Spread with Array in JavaScript | SamanthaMing.com
So let's use the Spread syntax to "erase" the brackets. const mergedArray = [ ...array1, ...array2 ]; mergedArray; // [ 1, 2, 3, 4, 5, 6 ] ๐Ÿ‘ˆ โœ… Nice flattened array ยท Cloning array in JavaScript isn't as straight forward.
๐ŸŒ
Dmitri Pavlutin
dmitripavlutin.com โ€บ javascript-merge-arrays
3 Ways to Merge Arrays in JavaScript
January 28, 2023 - You can use either the spread operator [...array1, ...array2], or a functional way [].concat(array1, array2) to merge 2 or more arrays.
๐ŸŒ
Mastering JS
masteringjs.io โ€บ tutorials โ€บ fundamentals โ€บ merge-arrays
3 Patterns to Merge Arrays in JavaScript - Mastering JS
Merging 2 arrays in JavaScript means combining the elements from two arrays to create a new, bigger array. We recommend using the spread operator to create a new array with the merged values.
Top answer
1 of 8
267

concat and spreads are very different when the argument is not an array.

When the argument is not an array, concat adds it as a whole, while ... tries to iterate it and fails if it can't. Consider:

a = [1, 2, 3]
x = 'hello';

console.log(a.concat(x));  // [ 1, 2, 3, 'hello' ]
console.log([...a, ...x]); // [ 1, 2, 3, 'h', 'e', 'l', 'l', 'o' ]

Here, concat treats the string atomically, while ... uses its default iterator, char-by-char.

Another example:

x = 99;

console.log(a.concat(x));   // [1, 2, 3, 99]
console.log([...a, ...x]);  // TypeError: x is not iterable

Again, for concat the number is an atom, ... tries to iterate it and fails.

Finally:

function* gen() { yield *'abc' }

console.log(a.concat(gen()));   // [ 1, 2, 3, Object [Generator] {} ]
console.log([...a, ...gen()]);  // [ 1, 2, 3, 'a', 'b', 'c' ]

concat makes no attempt to iterate the generator and appends it as a whole, while ... nicely fetches all values from it.

To sum it up, when your arguments are possibly non-arrays, the choice between concat and ... depends on whether you want them to be iterated.

The above describes the default behaviour of concat, however, ES6 provides a way to override it with Symbol.isConcatSpreadable. By default, this symbol is true for arrays, and false for everything else. Setting it to true tells concat to iterate the argument, just like ... does:

str = 'hello'
console.log([1,2,3].concat(str)) // [1,2,3, 'hello']

str = new String('hello');
str[Symbol.isConcatSpreadable] = true;
console.log([1,2,3].concat(str)) // [ 1, 2, 3, 'h', 'e', 'l', 'l', 'o' ]

Performance-wise concat is faster, probably because it can benefit from array-specific optimizations, while ... has to conform to the common iteration protocol. Timings:

let big = (new Array(1e5)).fill(99);
let i, x;

console.time('concat-big');
for(i = 0; i < 1e2; i++) x = [].concat(big)
console.timeEnd('concat-big');

console.time('spread-big');
for(i = 0; i < 1e2; i++) x = [...big]
console.timeEnd('spread-big');


let a = (new Array(1e3)).fill(99);
let b = (new Array(1e3)).fill(99);
let c = (new Array(1e3)).fill(99);
let d = (new Array(1e3)).fill(99);

console.time('concat-many');
for(i = 0; i < 1e2; i++) x = [1,2,3].concat(a, b, c, d)
console.timeEnd('concat-many');

console.time('spread-many');
for(i = 0; i < 1e2; i++) x = [1,2,3, ...a, ...b, ...c, ...d]
console.timeEnd('spread-many');
2 of 8
90

.concat() is faster, otherwise they work the same assuming both arguments are lists. Here's the time it takes to merge two arrays with 10 million elements each (lower is better):

Browser [...a, ...b] a.concat(b)
Chrome 113 350ms 30ms
Firefox 113 400ms 63ms
Safari 16.4 92ms 71ms

I ran this code on an M1 MacBook Air with 8GB of RAM:

const arraySize = 10000000;
const trials = 50;

const array1 = [];
const array2 = [];
for (let i = 0; i < arraySize; ++i) {
  array1.push(i);
  array2.push(i);
}

let spreadTime = 0;
for (let i = 0; i < trials; ++i) {
  const start = performance.now();
  const array3 = [...array1, ...array2];
  const end = performance.now();

  spreadTime += end - start;
}

let concatTime = 0;
for (let i = 0; i < trials; ++i) {
  const start = performance.now();
  const array3 = array1.concat(array2);
  const end = performance.now();

  concatTime += end - start;
}

// performance.now() returns milliseconds with a
// 5 microsecond resolution in isolated contexts and a
// 100 microsecond resolution in non-isolated contexts.
spreadTime = Math.round(spreadTime / trials * 1000) / 1000;
concatTime = Math.round(concatTime / trials * 1000) / 1000;
console.log(`${arraySize} items - spread: ${spreadTime}ms concat: ${concatTime}ms`);
๐ŸŒ
Codingem
codingem.com โ€บ home โ€บ how to merge arrays in javascript (5 easy ways)
How to Merge Arrays in JavaScript (5 Easy Ways)
July 10, 2025 - Thanks to the spread operator, merging arrays is much easier with a convenient syntax. ... The spread operator takes a copy of each value from the arrays and places them into the merged array.
๐ŸŒ
Medium
cleverzone.medium.com โ€บ demystifying-javascript-spread-operat-71924c888a8
Demystifying JavaScript : Spread operator (โ€ฆ) | by Cleverzone | Medium
August 26, 2023 - The spread operator simplifies the process of concatenating arrays, making the code more readable and expressive. Just as the spread operator can merge arrays, it can also merge objects.
๐ŸŒ
30 Seconds of Code
30secondsofcode.org โ€บ home โ€บ javascript โ€บ array โ€บ merge arrays
How do I merge two arrays in JavaScript? - 30 seconds of code
June 12, 2021 - The spread operator (...) was introduced in ES6 and can be used to merge two or more arrays, by spreading each one inside a new array:
๐ŸŒ
StudySmarter
studysmarter.co.uk โ€บ javascript spread and rest
Javascript Spread And Rest: Explained & Examples
Javascript Spread and Rest: Tools for handling arrays and objects efficiently. Spread Operator: Used to expand elements of arrays or objects into individual components, useful for merging and cloning (e.g., [...array1, ...array2]).
๐ŸŒ
Jonlinnell
jonlinnell.co.uk โ€บ articles โ€บ spread-operator-performance
How slow is the Spread operator in JavaScript? | Jon Linnell
By eight-digits, the difference is enormous; Array.concat() merged 20,000,000 items into the same array 365ms faster than a spread-merge. This is down to how these two methods process data under-the-hood. I can't say for certain, and I'll be damned if I'm going to do any research that involves reading the native C++ implementation of Array prototype functions. My semi-educated guess, given the disparity in timings we see, is that the spread operator is iterating one-by-one through each element, assigning each one to a new space in memory in sequence.