JAVASCRIPT / ARRAYS
Splice and slice for surgery on arrays
Copy any range of an array with slice and delete, insert, replace, or move items in place with splice.
What you will learn
- Copy a range with slice(start, end), where end is one past the last item kept
- Edit in place with splice(index, deleteCount, ...itemsToInsert)
- Read splice's return value as the removed items, never as the updated array
- Use negative start values in both methods to count backwards from the end
Understanding Splice and slice for surgery on arrays
Both methods take an index, but only one of them changes the array you call it on. slice(start, end) copies the items from start up to but not including end into a brand new array, so the original keeps its length and its contents. The exclusive end is deliberate: end minus start is exactly how many items you get, and consecutive calls like slice(0, 2) and slice(2, 4) fit together with no overlap and nothing skipped.
splice is the editing tool, and its second argument is a count, not an index, which is the single difference that causes most of the confusion between the two names. Because it works in place, the length changes and every index after the cut point shifts, so any position you were holding on to, including a loop counter, is immediately stale. Its return value is the array of removed items, so const result = arr.splice(...) hands you the debris, not the repaired array; the result of the edit is arr itself.
It helps to picture the array as a paper strip. slice photocopies a marked section and gives you the copy; splice takes scissors to one spot, cuts out deleteCount items, and tapes in whatever replacements you pass. Nothing requires those two counts to match, which is why one call can delete two items and insert five, shrinking or growing the array in a single step. Negative start values in both methods count backwards from the end, so slice(-3) means the last three items without ever mentioning length.
const colors = ["red", "green", "blue", "yellow", "purple"];
const middle = colors.slice(1, 3);
console.log(middle, colors.length);
const removed = colors.splice(1, 2, "cyan");
console.log(removed);
console.log(colors, colors.length);slice reads a range into a new array and leaves the original intact, while splice rewrites the original at one position and returns only what it cut out.
Worked examples
Inserting without deleting
A deleteCount of 0 turns splice into a pure insertion at any position.
const steps = ["wash", "dry", "fold"];
const removed = steps.splice(1, 0, "rinse");
console.log(removed, removed.length);
console.log(steps);
steps.splice(-1, 1);
console.log(steps);Example explained
Line 1splice(1, 0, "rinse") deletes nothing and inserts at index 1, pushing "dry" and "fold" one slot to the right.
Line 2The return value is still an array, just an empty one, so code that iterates the result never breaks.
Line 3splice(-1, 1) resolves -1 to the last index, removing "fold" without mentioning steps.length.
Ranges and negative ends with slice
How slice resolves negative indexes and what happens when end lands before start.
const scores = [10, 20, 30, 40];
console.log(scores.slice(-2));
console.log(scores.slice(0, -1));
console.log(scores.slice(2, 1));
console.log(scores);Example explained
Line 1slice(-2) counts two positions back from the end and runs to the end, giving the last two scores.
Line 2slice(0, -1) excludes its end index, so the final element is dropped instead of kept.
Line 3slice(2, 1) has an end before its start, which yields [] rather than throwing or reversing the range.
Line 4The last log confirms scores itself never changed, because slice only reads.
Moving an item with two splices
Uses splice's return value to lift one element out and drop it back in at a new index.
const playlist = ["intro", "verse", "chorus", "outro"];
const [moved] = playlist.splice(2, 1);
console.log(moved);
playlist.splice(1, 0, moved);
console.log(playlist);Example explained
Line 1splice(2, 1) removes exactly one item and returns it wrapped in a one-element array.
Line 2Destructuring with [moved] unwraps that array so moved is the string, not ["chorus"].
Line 3After the removal, "outro" has slid down to index 2, so the insertion index refers to the shortened array.
Line 4The second call uses deleteCount 0, which completes the move without disturbing anything else.
Important notes
slice copies element references, not the elements themselves, so const copy = users.slice() gives a new array whose objects are still the originals; mutating copy[0].name is visible through users[0].name.
Omitting deleteCount is not the same as passing 0: arr.splice(1) removes everything from index 1 onward, while arr.splice(1, 0) removes nothing. If you want splice semantics without mutation, arr.toSpliced(...) returns a new array in newer engines.
Common mistakes
Writing const shorter = list.splice(0, 1) and then using shorter as the trimmed list: shorter is the single removed item, and list is the one that got shortened.
Treating splice's second argument as an end index, so splice(1, 3) deletes three items starting at index 1 instead of the two items between index 1 and index 3.
Calling arr.splice(i, 1) inside a forward for loop: the next element slides into index i, and i++ steps over it, so every second match survives.
Try it yourself
Change, predict, then run
Start from ["Mon", "Tue", "Thu", "Fri"] and use a single splice call to insert "Wed" in the right position. Then log arr.slice(-2) and arr.length to confirm the copy holds two days while the original now has five.
Open the JavaScript workspaceCheck your understanding
After const arr = [1, 2, 3, 4, 5]; const out = arr.splice(1, 2); what do out and arr contain?
- out is [2, 3] and arr is [1, 4, 5]
- out is [1, 4, 5] and arr is [1, 2, 3, 4, 5]
- out is [2, 3] and arr is [1, 2, 3, 4, 5]
- out is [2] and arr is [1, 3, 4, 5]
Show answer
splice deletes two items starting at index 1 and returns those deleted items, so out is [2, 3] and arr is left as [1, 4, 5]. The option showing out as [1, 4, 5] is tempting because many methods return the new collection, but splice hands back the removed slice and reports its result through the original array. The [2] option comes from misreading the 2 as an end index, which is slice's convention, not splice's.