489

I'm trying to push multiple elements as one array, but getting an error:

> a = []
[]
> a.push.apply(null, [1,2])
TypeError: Array.prototype.push called on null or undefined

I'm trying to do similar stuff that I'd do in ruby, I was thinking that apply is something like *.

>> a = []
=> []
>> a.push(*[1,2])
=> [1, 2]
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
evfwcqcg
  • 15,755
  • 15
  • 55
  • 72

10 Answers10

850

You can push multiple elements into an array in the following way

var a = [];
    
a.push(1, 2, 3);

console.log(a);
amit1310
  • 8,825
  • 2
  • 12
  • 12
  • 1
    This answer and the selected answer produce different, and perhaps unexpected, results. a.push(1) vs. a.push([1]) – oevna Dec 24 '16 at 01:12
  • 3
    Can anyone explain, why this has so many more votes than the accepted answer? It might be easier, but is less flexible. If you want to merge 2 arrays, this wont work. – Tigerware Sep 17 '19 at 14:49
  • 3
    @BluE if you want to merge two arrays just use array.concat() – Florent Arlandis Feb 26 '20 at 16:45
  • 2
    @FlorentArlandis array.concat does not work to add the 2nd array to the first. It will create a new one. I know it is similar. The spread operator is what I was looking for. Just look at the other answers and comments there for details. – Tigerware Feb 27 '20 at 07:55
  • 10
    @BluE ES6 now allow you to do something like this ```array1.push(...array2)``` that works exactly like ```array1.push(array2[0], array2[1], array2[2])``` except a limitation of number of elements in array2 (about 100,000) – vantrung -cuncon Sep 06 '20 at 21:12
682

Now in ECMAScript2015 (a.k.a. ES6), you can use the spread operator to append multiple items at once:

var arr = [1];
var newItems = [2, 3];
arr.push(...newItems);
console.log(arr);

See Kangax's ES6 compatibility table to see what browsers are compatible

John
  • 7,114
  • 2
  • 37
  • 57
canac
  • 15,440
  • 2
  • 16
  • 11
315

When using most functions of objects with apply or call, the context parameter MUST be the object you are working on.

In this case, you need a.push.apply(a, [1,2]) (or more correctly Array.prototype.push.apply(a, [1,2]))

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
94

As one alternative, you can use Array.concat:

var result = a.concat(b);

This would create and return a new array instead of pushing items to the same array. It can be useful if you don't want to modify the source array but rather make a shallow copy of it.

VisioN
  • 143,310
  • 32
  • 282
  • 281
  • 31
    Array.prototype.concat returns new array. – suricactus Aug 21 '15 at 21:38
  • 12
    He wants to push to existing array so `Array.prototype.push.apply(arr1, arr2)` is the correct answer, because using `arr1.concat(arr2)` you are creating a new array. – suricactus Aug 21 '15 at 22:18
  • 4
    @suricactus `arr1 = arr1.concat(arr2)` is not a big deal and looks much cleaner. Pushing to old array or replacing old array with the new one depends on your needs. If you deal with 10m+ elements pushing to old array will work faster, if you manage small chunks you hardly find any difference in speed. Both options a completely legit. – VisioN Aug 21 '15 at 22:47
  • Are you guys sure `prototype.push.apply` works faster than `.concat`? I think `apply` might actually be slower, since it probably calls `push` again and again for each item in `arr2` – Yuval A. May 09 '16 at 12:08
  • 5
    @YuvalA. `prototype.push.apply` only calls `push` once. And the distinction above isn't necessary about speed but an in-place operation vs creating a new array. What if I had a method that took an array and was supposed to modify it in-place? The `concat` method cannot possibly work, even with VisionN's code as it won't modify the variable for the caller of the function. – coderforlife Sep 02 '16 at 14:58
  • Not considering the fact it does not A the Q, I want to add that the reason using `.concat` is 'slow', or inefficient, especially with large arrays, is because the VM will need to GC the old array, impacting performance considerably. – origo Aug 22 '17 at 13:13
  • @origo Are you sure about that? Optimisation mechanisms are not that stupid and may "understand" your intensions. For example, the best way to append values to array (slice) in Golang is doing `a = append(a, 1, 2, 3)`, although internally `append` will always return a new slice. Same may work in JS, as the new array will immediately replace the old one in memory. Anyway, this is all theory, we need JSPerf here to prove the word "considerably". And yes, it does A the Q, as it does exactly what is required, if used as `a = a.concat([1, 2, 3])`. – VisioN Aug 23 '17 at 18:45
  • 1
    ```a = a.concat(b)``` is still a shorter syntax than ```Array.prototype.push.apply(arr1, arr2)``` – Aizzat Suhardi Nov 07 '17 at 04:52
  • Please do not treat `a = a.concat` as equivalent to `push`. This does not just come down to syntax preference, it is not the same operation. Using concat only updates a *single* reference to the array (`a`). If there any other references to the same array anywhere else in your app, they will *not* see the update. If the goal is to update an array rather than work with a new one, always use `push`. – nmclean Nov 15 '22 at 01:37
  • 1
    @nmclean This answer is so old that I have almost forgotten about it. I have updated it and included a note, so it's obvious to everyone that these two methods are not equivalent. – VisioN Nov 15 '22 at 12:49
71

If you want to add multiple items, you can use Array.push() together with the spread operator:

a = [1,2]
b = [3,4,5,6]
a.push(...b)

The result will be

a === [1,2,3,4,5,6]
miken32
  • 42,008
  • 16
  • 111
  • 154
Nikhil Yadav
  • 1,419
  • 1
  • 13
  • 8
28

If you want an alternative to Array.concat in ECMAScript 2015 (a.k.a. ES6, ES2015) that, like it, does not modify the array but returns a new array you can use the spread operator like so:

var arr = [1];
var newItems = [2, 3];
var newerItems = [4, 5];
var newArr = [...arr, ...newItems, ...newerItems];
console.log(newArr);

Note this is different than the push method as the push method mutates/modifies the array.

If you want to see if certain ES2015 features work in your browser check Kangax's compatibility table.

You can also use Babel or a similar transpiler if you do not want to wait for browser support and want to use ES2015 in production.

John
  • 7,114
  • 2
  • 37
  • 57
4

Easier way is

a = []
a.push(1,2,3)

Another way is

a = [...a, 4,5,6]

if you want to create another array

const b = a.concat(7,8,9)
MD SHAYON
  • 7,001
  • 45
  • 38
  • 2
    Easier than what? These are the exact approaches given in [this 10 year old answer](https://stackoverflow.com/a/14723896/1255289) and [this 7 year old answer](https://stackoverflow.com/a/35167699/1255289) – miken32 Sep 13 '22 at 18:21
4

I had the same doubt and in my case, an easier solution worked for me:

let array = []
array.push(1, 2, 4, "string", new Object())
console.log(array)
// logs [ 1, 2, 4, 'string', {} ]
Jose Velasco
  • 180
  • 2
  • 8
  • Easier than what? This is the exact approach given in [this 10 year old answer](https://stackoverflow.com/a/14723896/1255289) – miken32 Sep 13 '22 at 18:20
  • Does copying the same comment over and over give you points? I try to contribute, others... – Jose Velasco Sep 14 '22 at 19:55
0

Pushing multiple objects at once often depends on how are you declaring your array.

This is how I did

//declaration
productList= [] as  any;

now push records

this.productList.push(obj.lenght, obj2.lenght, items);
R15
  • 13,982
  • 14
  • 97
  • 173
  • 2
    "Type assertion expressions can only be used in TypeScript files." is what VS Code said about the keyword `any` here – Ramon Dias Mar 06 '21 at 05:02
0

Imagine you have an array of first ten numbers but missing a number, say 6. You can insert it into the array at the index 5 with the following code

function insert(array, index, obj) {
  return [...array.slice(0,index), obj, ...array.slice(index)]
}

let arr = [1,2,3,4,5,7,8,9,0]
arr = insert(arr, 5, 6)
console.log(arr)
Mohamed Anas
  • 194
  • 2
  • 7