JavaScript Array Splice Method: Complete Tutorial

Master the JavaScript splice() method for adding, removing, and replacing elements in arrays. Covers syntax, return values, insertion patterns, batch operations, and how splice compares to slice and other array methods.

JavaScriptbeginner
12 min read

The splice() method is the Swiss Army knife of array mutation in JavaScript. Unlike push(), pop(), shift(), and unshift() which only work at the ends, splice() can add, remove, or replace elements at any position within an array. It is the only built-in method that combines all three operations in a single call.

Syntax

javascriptjavascript
array.splice(start)
array.splice(start, deleteCount)
array.splice(start, deleteCount, item1, item2, ..., itemN)
ParameterTypeDescription
startNumberIndex where the operation begins. Negative values count from the end
deleteCountNumber (optional)Number of elements to remove starting from start. Defaults to everything from start to the end
item1...itemNAny (optional)Elements to insert at the start position

Return value: An array containing the deleted elements. If no elements were deleted, returns an empty array [].

Removing Elements

Remove a Specific Number of Elements

javascriptjavascript
const colors = ["red", "orange", "yellow", "green", "blue"];
 
// Remove 2 elements starting at index 1
const removed = colors.splice(1, 2);
 
console.log(removed); // ["orange", "yellow"]
console.log(colors);  // ["red", "green", "blue"]

Remove Everything from an Index Onward

Omit the deleteCount parameter:

javascriptjavascript
const items = ["keep", "keep", "remove", "remove", "remove"];
 
const tail = items.splice(2);
console.log(tail);  // ["remove", "remove", "remove"]
console.log(items); // ["keep", "keep"]

Remove a Single Element by Index

javascriptjavascript
const fruits = ["apple", "banana", "cherry", "date"];
 
// Remove the element at index 2
fruits.splice(2, 1);
console.log(fruits); // ["apple", "banana", "date"]

Remove an Element by Value

Combine indexOf() with splice():

javascriptjavascript
const tags = ["JavaScript", "Python", "Rust", "Go"];
 
const index = tags.indexOf("Python");
if (index !== -1) {
  tags.splice(index, 1);
}
 
console.log(tags); // ["JavaScript", "Rust", "Go"]
Always Check indexOf

indexOf() returns -1 if the value is not found. Calling splice(-1, 1) without checking would remove the last element of the array rather than doing nothing. Always guard with an if (index !== -1) check.

Inserting Elements

Set deleteCount to 0 to insert without removing anything:

javascriptjavascript
const steps = ["Plan", "Build", "Deploy"];
 
// Insert "Test" at index 2 (between "Build" and "Deploy")
steps.splice(2, 0, "Test");
console.log(steps); // ["Plan", "Build", "Test", "Deploy"]

Insert Multiple Elements

javascriptjavascript
const letters = ["a", "d", "e"];
 
// Insert "b" and "c" at index 1
letters.splice(1, 0, "b", "c");
console.log(letters); // ["a", "b", "c", "d", "e"]

Insert at the Beginning

javascriptjavascript
const queue = ["second", "third"];
 
queue.splice(0, 0, "first");
console.log(queue); // ["first", "second", "third"]
// Equivalent to unshift("first"), but splice lets you insert multiple items in the same call

Insert at the End

javascriptjavascript
const list = ["a", "b"];
 
list.splice(list.length, 0, "c", "d");
console.log(list); // ["a", "b", "c", "d"]
// Equivalent to push("c", "d")

Replacing Elements

Remove and insert in a single operation:

javascriptjavascript
const team = ["Alice", "Bob", "Carol", "Dave"];
 
// Replace "Bob" (index 1) with "Bobby" and "Brian"
const replaced = team.splice(1, 1, "Bobby", "Brian");
 
console.log(replaced); // ["Bob"]
console.log(team);     // ["Alice", "Bobby", "Brian", "Carol", "Dave"]

Replace a Range

javascriptjavascript
const schedule = ["Mon", "Tue", "Wed", "Thu", "Fri"];
 
// Replace Wed-Thu with a single "Midweek" entry
schedule.splice(2, 2, "Midweek");
console.log(schedule); // ["Mon", "Tue", "Midweek", "Fri"]

Negative Start Index

Negative values count backward from the end. -1 is the last element, -2 is second-to-last:

javascriptjavascript
const nums = [10, 20, 30, 40, 50];
 
// Remove last 2 elements
const last2 = nums.splice(-2);
console.log(last2); // [40, 50]
console.log(nums);  // [10, 20, 30]
javascriptjavascript
const arr = [1, 2, 3, 4, 5];
 
// Insert at second-to-last position
arr.splice(-1, 0, 4.5);
console.log(arr); // [1, 2, 3, 4, 4.5, 5]

Practical splice() Operation Summary

Goalsplice() callExample result
Remove 1 at index iarr.splice(i, 1)Removes arr[i]
Remove N from index iarr.splice(i, n)Removes N elements
Remove all from index iarr.splice(i)Removes everything from i onward
Insert at index iarr.splice(i, 0, x)Inserts x before arr[i]
Replace at index iarr.splice(i, 1, x)Replaces arr[i] with x
Replace N at index iarr.splice(i, n, ...items)Removes N, inserts items

Real-World Patterns

Reordering List Items (Drag and Drop)

Moving an element from one position to another:

javascriptjavascript
function moveItem(arr, fromIndex, toIndex) {
  const [item] = arr.splice(fromIndex, 1); // Remove from old position
  arr.splice(toIndex, 0, item);            // Insert at new position
  return arr;
}
 
const playlist = ["Song A", "Song B", "Song C", "Song D", "Song E"];
moveItem(playlist, 4, 1); // Move "Song E" to position 1
console.log(playlist); // ["Song A", "Song E", "Song B", "Song C", "Song D"]

Removing All Matching Elements

Remove every occurrence of a value:

javascriptjavascript
function removeAll(arr, value) {
  let index = arr.indexOf(value);
  while (index !== -1) {
    arr.splice(index, 1);
    index = arr.indexOf(value);
  }
  return arr;
}
 
const data = [1, 2, 3, 2, 4, 2, 5];
removeAll(data, 2);
console.log(data); // [1, 3, 4, 5]

For the immutable version, use filter():

javascriptjavascript
const data = [1, 2, 3, 2, 4, 2, 5];
const clean = data.filter(n => n !== 2);
console.log(clean); // [1, 3, 4, 5]
console.log(data);  // [1, 2, 3, 2, 4, 2, 5] โ€” unchanged

Inserting in Sorted Position

Maintaining a sorted array by inserting at the correct position:

javascriptjavascript
function insertSorted(sortedArr, value) {
  let insertIndex = sortedArr.findIndex(el => el > value);
  if (insertIndex === -1) insertIndex = sortedArr.length;
  sortedArr.splice(insertIndex, 0, value);
  return sortedArr;
}
 
const sorted = [10, 20, 30, 40, 50];
insertSorted(sorted, 25);
console.log(sorted); // [10, 20, 25, 30, 40, 50]
 
insertSorted(sorted, 5);
console.log(sorted); // [5, 10, 20, 25, 30, 40, 50]
 
insertSorted(sorted, 60);
console.log(sorted); // [5, 10, 20, 25, 30, 40, 50, 60]

Batch Replace with Validation

Replacing a section of an array with validated data:

javascriptjavascript
function updateSection(items, startIndex, newItems) {
  if (startIndex < 0 || startIndex >= items.length) {
    throw new RangeError(`Start index ${startIndex} is out of bounds`);
  }
 
  const validItems = newItems.filter(item => item != null && item !== "");
 
  if (validItems.length === 0) {
    console.warn("No valid items to insert");
    return [];
  }
 
  return items.splice(startIndex, validItems.length, ...validItems);
}
 
const inventory = ["Widget A", "Widget B", "Widget C", "Widget D"];
const replaced = updateSection(inventory, 1, ["Widget X", "Widget Y"]);
console.log(replaced);   // ["Widget B", "Widget C"]
console.log(inventory);  // ["Widget A", "Widget X", "Widget Y", "Widget D"]

splice() vs slice() Quick Reference

This is one of the most confused pairs in JavaScript. For a detailed breakdown, see the full slice vs splice comparison.

Featuresplice()slice()
Mutates originalYesNo
PurposeAdd, remove, replace in placeExtract a portion into new array
ReturnsArray of removed elementsNew array with extracted elements
Second parameterDelete countEnd index (exclusive)
Inserts elementsYes (3rd+ parameters)No

Performance Considerations

splice() has different performance characteristics depending on where it operates:

OperationPositionTime complexity
Remove from endsplice(-1, 1)O(1)
Remove from startsplice(0, 1)O(n)
Remove from middlesplice(mid, 1)O(n)
Insert at endsplice(length, 0, x)O(1)
Insert at startsplice(0, 0, x)O(n)
Insert at middlesplice(mid, 0, x)O(n)

Any operation that affects the beginning or middle forces the engine to re-index all subsequent elements.

Splice in Loops

Avoid calling splice() inside a forward-iterating loop. Each removal shifts indices, causing you to skip elements. Either iterate backward, accumulate indices and remove in reverse, or use filter() for removal by condition.

Common Mistakes

Confusing splice() with slice():

javascriptjavascript
const arr = [1, 2, 3, 4, 5];
 
// Developer wanted a copy of elements 1-3 (non-destructive)
const result = arr.splice(1, 3); // Oops: mutated the array!
console.log(arr);    // [1, 5]
console.log(result); // [2, 3, 4]
 
// Should have used slice()
// const result = arr.slice(1, 4);

Splicing during forward iteration:

javascriptjavascript
// Bug: skips elements after removal
const numbers = [1, 2, 3, 4, 5, 6];
for (let i = 0; i < numbers.length; i++) {
  if (numbers[i] % 2 === 0) {
    numbers.splice(i, 1);
    // After removing index 1 (value 2), value 3 shifts to index 1
    // but i increments to 2, skipping 3
  }
}
console.log(numbers); // [1, 3, 5] โ€” works by luck, but unreliable
 
// Fix: iterate backward
const nums = [1, 2, 3, 4, 5, 6];
for (let i = nums.length - 1; i >= 0; i--) {
  if (nums[i] % 2 === 0) {
    nums.splice(i, 1);
  }
}
console.log(nums); // [1, 3, 5] โ€” correct

Forgetting deleteCount (removes everything):

javascriptjavascript
const arr = [1, 2, 3, 4, 5];
 
// Bug: developer wanted to insert at index 2, forgot deleteCount
arr.splice(2, "new"); // "new" coerces to NaN, treated as 0 โ€” nothing is deleted
 
// The safe way: always specify deleteCount explicitly
arr.splice(2, 0, "new"); // Insert "new" at index 2, delete nothing
Rune AI

Rune AI

Key Insights

  • Three-in-one method: splice() removes, inserts, and replaces elements at any array position
  • Mutates the original: Always modifies the array in place; returns an array of removed elements
  • Second parameter is a count: splice(2, 3) removes 3 elements starting at index 2 (not "up to index 3")
  • Insert pattern: splice(index, 0, ...items) inserts without removing by setting deleteCount to 0
  • Loop safety: Never splice in a forward loop; iterate backward or use filter() for condition-based removal
RunePowered by Rune AI

Frequently Asked Questions

Does splice() return the modified array?

No. `splice()` returns an array of the removed elements, not the modified array. The original array is modified in place. If no elements were removed, the return value is an empty array `[]`.

How do I remove an element by value instead of by index?

First find the index with `indexOf()`, then splice: `const i = arr.indexOf(value); if (i !== -1) arr.splice(i, 1);`. Always check that `indexOf` did not return `-1` before splicing, or you will accidentally remove the last element.

What happens if deleteCount is 0?

If `deleteCount` is 0, `splice()` removes nothing and only inserts the new items at the `start` position. This is the standard pattern for pure insertion. The return value will be an empty array.

Can splice() add and remove at the same time?

Yes. That is one of its key features. `arr.splice(2, 1, "new")` removes one element at index 2 and inserts `"new"` in its place. You can remove N elements and insert M elements in a single call, and they do not need to be the same count.

Is splice() or filter() better for removing elements?

Use `splice()` when you know the exact index and want to mutate the original array. Use `filter()` when removing by condition and you want a new array without mutation. In modern JavaScript with immutable state patterns, `filter()` is generally preferred because it avoids side effects.

Conclusion

The splice() method handles every in-place array modification scenario: removing elements by index, inserting at any position, and replacing sections in a single call. Its versatility makes it indispensable for drag-and-drop reordering, sorted insertions, and batch updates. The essential details to remember are that it mutates the original array, the second parameter is a count (not an end index like slice), and forward-loop splicing skips elements. When mutation is unacceptable, prefer filter() for removals and spread syntax for insertions.