Array.prototype.push()
push(...items) push() adds one or more elements to the end of an array and returns the new length of the array. It modifies the array in place.
Syntax
arr.push(element1)
arr.push(element1, element2)
arr.push(element1, element2, /* ... */ elementN)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
items | any | — | The element(s) to add to the end of the array. Accepts multiple arguments. |
The items parameter is variadic — you can pass zero or more values of any type. Each argument is appended to the array in the order it appears in the call. When you pass no arguments, push() simply returns the current length without modifying the array.
Examples
Basic usage
const fruits = ["apple", "banana"];
const newLength = fruits.push("cherry");
console.log(fruits); // ["apple", "banana", "cherry"]
console.log(newLength); // 3
The return value is the new array length, not the appended element. When you only need to know the updated size, you can store it directly. Pass several arguments to push() and each one is appended in the order provided — the elements land at the end in the same sequence you pass them.
Adding multiple elements
const nums = [1, 2, 3];
const newLength = nums.push(4, 5, 6);
console.log(nums); // [1, 2, 3, 4, 5, 6]
console.log(newLength); // 6
Calling push() with multiple arguments is equivalent to calling it repeatedly with each argument in the same order, but the single call is both cleaner to read and avoids triggering intermediate side effects that separate calls might cause. The return value reflects the total after all arguments have been appended.
Using push with zero arguments
const arr = [1, 2, 3];
const length = arr.push();
console.log(length); // 3 (no change)
When called with no arguments, push() is effectively a no-op that returns the current array length. While uncommon in production code, this behavior is worth knowing because it means you never need to guard against an empty argument list. The three examples above cover the core calling conventions: a single element, multiple elements, and the edge case of zero arguments.
Common Patterns
Building an array dynamically
const results = [];
for (let i = 0; i < 5; i++) {
results.push(i * 2);
}
console.log(results); // [0, 2, 4, 6, 8]
This pattern is common in data processing pipelines where you transform elements one at a time and collect the output. The loop pushes each transformed value, so the final array preserves the iteration order. When the transformation logic is a pure mapping, Array.prototype.map() is more concise, but push() inside a loop gives you room to skip items or run side effects per iteration.
Queue with push (and shift for dequeue)
class Queue {
constructor() {
this.items = [];
}
enqueue(item) {
this.items.push(item);
}
dequeue() {
return this.items.shift();
}
peek() {
return this.items[0];
}
}
const queue = new Queue();
queue.enqueue("first");
queue.enqueue("second");
console.log(queue.dequeue()); // "first"
The combination of push() (enqueue) and shift() (dequeue) creates a classic FIFO queue. Each enqueue appends to the end and each dequeue removes from the front, so items leave in the same order they arrived. For simple queueing needs this pattern works well, though shift() is O(n) and can become a bottleneck on large arrays.
Converting iterable to array
const str = "hello";
const chars = [];
for (const char of str) {
chars.push(char);
}
console.log(chars); // ["h", "e", "l", "l", "o"]
This technique converts any iterable into a genuine array. While Array.from() accomplishes the same thing in a single expression, a manual push() loop makes the conversion explicit and gives you a place to filter or transform elements on the fly. For strings specifically, str.split('') is the idiomatic one-liner, but the push() approach generalises to any iterable — sets, maps, generators, or custom iterable objects.
Behavior Notes
push()accepts zero arguments, which returns the current length without changes- This method modifies the original array (mutating method)
- Returns the new length of the array, not the added elements
How push() works
push() appends each argument to the end of the array in order, incrementing length for each. When called with multiple arguments, they are appended left to right — arr.push(1, 2, 3) produces the same result as three separate push calls in the same order. The return value is the updated length of the array after all arguments have been appended.
Performance
push() is an O(1) amortized operation. JavaScript engines pre-allocate extra capacity when an array grows, so most push calls simply write to an existing slot. Occasional reallocation happens when capacity is exhausted, but the amortized cost across many calls remains constant. This makes repeated push() much more efficient than repeated unshift(), which is always O(n) because every existing element must be shifted.
When push() is the right primitive
push() is the default choice when you are building a collection in order and the end of the array represents the newest item. It is a natural match for logs, buffers, queues being filled from the back, and any workflow that wants to accumulate data step by step. The method is simple, fast, and easy to read because it maps directly to “append to the end.”
Immutable alternative
push() mutates the array. For immutable code — React state, Redux reducers, or functional pipelines — use the spread operator or concat() to create a new array:
const arr = [1, 2, 3];
// Mutating
arr.push(4); // arr is now [1, 2, 3, 4]
// Non-mutating
const newArr = [...arr, 4]; // arr unchanged
const newArr2 = arr.concat(4); // equivalent
The spread operator and concat() both avoid mutation, but they differ in how they handle nested structures — neither does a deep copy, so nested objects and arrays are shared between the original and the new array. For React state updates that involve nested data, you may need to combine the spread operator with explicit copying of nested values.
Pushing multiple values from another array
To push all elements of one array into another, use the spread operator rather than a loop:
const a = [1, 2];
const b = [3, 4, 5];
a.push(...b); // a is now [1, 2, 3, 4, 5]
For very large b, spreading can exceed the call stack limit. In that case, use Array.prototype.push.apply(a, b) or a loop.
See Also
- Array.prototype.shift() — Remove the first element
- Array.prototype.unshift() — Add elements to the start
- Array.prototype.concat() — Merge arrays without mutation
- Array.prototype.splice() — Add/remove elements at any position