To extend an existing JavaScript array with another array without creating a new array, you need to modify the original array in place. Below are methods to achieve this, along with detailed explanations and examples.
1. Using Array.prototype.push()
with the Spread Operator
The push()
method appends elements to the end of an array. Use the spread operator (...
) to expand the second array into individual elements.
const arr1 = [1, 2];
const arr2 = [3, 4];
// Extend arr1 with arr2
arr1.push(...arr2);
console.log(arr1); // Output: [1, 2, 3, 4]
console.log(arr2); // Output: [3, 4] (unchanged)
Pros: Simple and concise.
Cons: May cause a stack overflow for very large arrays (due to argument limits).
2. Using Array.prototype.splice()
The splice()
method inserts elements at a specified index. Use the array’s length as the insertion point to append elements.
const arr1 = [1, 2];
const arr2 = [3, 4];
// Insert arr2 elements at the end of arr1
arr1.splice(arr1.length, 0, ...arr2);
console.log(arr1); // Output: [1, 2, 3, 4]
Pros: Flexible (can insert elements at any position).
Cons: Syntax is slightly more verbose.
3. Using Array.prototype.unshift()
for Prepend
To add elements to the beginning of an array, use unshift()
with the spread operator:
const arr1 = [3, 4];
const arr2 = [1, 2];
// Prepend arr2 to arr1
arr1.unshift(...arr2);
console.log(arr1); // Output: [1, 2, 3, 4]
Note: The order of elements in arr2
is preserved when prepended.
4. Using Array.prototype.apply()
(Legacy Approach)
Before ES6, apply()
was used to pass array elements as arguments to push()
:
const arr1 = [1, 2];
const arr2 = [3, 4];
// Extend arr1 with arr2
Array.prototype.push.apply(arr1, arr2);
console.log(arr1); // Output: [1, 2, 3, 4]
Pros: Works in older browsers.
Cons: Less readable; deprecated in favor of the spread operator.
5. Using a Loop (for Large Arrays)
For extremely large arrays (to avoid stack overflow with push(...arr)
):
const arr1 = [1, 2];
const arr2 = [3, 4];
// Append elements of arr2 to arr1
for (const element of arr2) {
arr1.push(element);
}
console.log(arr1); // Output: [1, 2, 3, 4]
Pros: Safe for very large arrays.
Cons: More verbose; slower for small arrays.
6. Merging Arrays In-Place with Array.prototype.length
Directly assign elements using the array’s length property:
const arr1 = [1, 2];
const arr2 = [3, 4];
// Start at index 2 (end of arr1) and append arr2 elements
arr2.forEach((element, index) => {
arr1[arr1.length + index] = element;
});
console.log(arr1); // Output: [1, 2, 3, 4]
Note: This avoids function calls but is less idiomatic.
Key Considerations
- Mutability: All methods modify the original array (
arr1
). - Performance:
- For small arrays:
push(...arr2)
is fastest. - For large arrays: Use a loop to avoid stack overflow.
- Order Preservation: Elements are added in the order they appear in
arr2
.
Edge Cases
Case 1: Empty Second Array
const arr1 = [1, 2];
const arr2 = [];
arr1.push(...arr2);
console.log(arr1); // Output: [1, 2] (no change)
Case 2: Nested Arrays
To flatten nested arrays before merging:
const arr1 = [1, 2];
const arr2 = [[3, 4], 5];
arr1.push(...arr2.flat());
console.log(arr1); // Output: [1, 2, 3, 4, 5]
Case 3: Non-Array Values
Handle non-array inputs:
const arr1 = [1, 2];
const arr2 = "hello"; // String (iterable)
arr1.push(...Array.from(arr2)); // Converts string to array
console.log(arr1); // Output: [1, 2, 'h', 'e', 'l', 'l', 'o']
Summary Table
Method | Example | Use Case |
---|---|---|
push(...arr2) | arr1.push(...arr2) | Simple appending |
splice() | arr1.splice(len, 0, ...arr2) | Insert at a specific index |
unshift(...arr2) | arr1.unshift(...arr2) | Prepend elements |
apply() (legacy) | Array.prototype.push.apply() | Compatibility with older JS |
Loop | for (const el of arr2) push(el) | Large arrays |
Final Notes
- Use
push(...arr2)
for most cases. - For very large arrays (>100,000 elements), use a loop to avoid stack overflow.
- Avoid
concat()
(it creates a new array).