Episode 1 — Fundamentals / 1.22 — Array Methods

1.22.f — slice() and splice()

In one sentence: slice() extracts a portion of an array into a new array without touching the original, while splice() adds, removes, or replaces elements in place, mutating the original array.

Navigation: ← 1.22.e — some() and every() · 1.22.g — sort() →


1. slice(start, end) — safe extraction

slice returns a shallow copy of a portion of the array, from index start up to (but not including) index end.

const letters = ["a", "b", "c", "d", "e"];

const middle = letters.slice(1, 4);
console.log(middle);  // ["b", "c", "d"]
console.log(letters); // ["a", "b", "c", "d", "e"]  ← unchanged

Syntax

arr.slice(start, end);
ParameterDescriptionDefault
startIndex to begin extraction (inclusive)0
endIndex to stop extraction (exclusive)arr.length
ReturnNew array containing extracted elements
Mutates?No

2. slice() with no arguments — shallow copy

Calling slice() with no arguments copies the entire array:

const original = [1, 2, 3];
const copy = original.slice();

copy.push(4);
console.log(original); // [1, 2, 3]   ← not affected
console.log(copy);     // [1, 2, 3, 4]

This is equivalent to [...original] or Array.from(original).

Warning — shallow copy: If the array contains objects, both arrays reference the same objects:

const users = [{ name: "Alice" }, { name: "Bob" }];
const copy = users.slice();

copy[0].name = "Alicia";
console.log(users[0].name); // "Alicia" — same object reference!

3. Negative indices in slice

Negative indices count from the end of the array:

const nums = [10, 20, 30, 40, 50];

nums.slice(-2);      // [40, 50]       — last 2 elements
nums.slice(-3, -1);  // [30, 40]       — from 3rd-to-last to 1st-to-last (exclusive)
nums.slice(1, -1);   // [20, 30, 40]   — from index 1 to second-to-last

Quick reference

CallResultExplanation
slice()Full copyNo args = entire array
slice(2)From index 2 to end[30, 40, 50]
slice(1, 3)Index 1 up to (not including) 3[20, 30]
slice(-2)Last 2 elements[40, 50]
slice(-3, -1)3rd-to-last up to last (exclusive)[30, 40]
slice(0, 0)Empty arrayStart = end

4. splice(start, deleteCount, ...items) — mutating modification

splice can remove, insert, or replace elements. It modifies the array in place.

Syntax

const removed = arr.splice(start, deleteCount, item1, item2, ...);
ParameterDescription
startIndex at which to start changing the array
deleteCountNumber of elements to remove (0 = insert only)
...items(optional) Elements to insert at start
ReturnArray of deleted elements (empty array if none deleted)
Mutates?Yes

5. Splice for deletion

const colors = ["red", "green", "blue", "yellow", "purple"];

// Remove 2 elements starting at index 1
const removed = colors.splice(1, 2);

console.log(removed); // ["green", "blue"]  ← what was removed
console.log(colors);  // ["red", "yellow", "purple"]  ← mutated!

Remove a single element by index

const fruits = ["apple", "banana", "cherry", "date"];
fruits.splice(2, 1); // remove 1 element at index 2

console.log(fruits); // ["apple", "banana", "date"]

Remove from the end using negative index

const nums = [1, 2, 3, 4, 5];
nums.splice(-2, 2); // remove last 2 elements

console.log(nums); // [1, 2, 3]

6. Splice for insertion

Set deleteCount to 0 to insert without removing:

const letters = ["a", "b", "e", "f"];

// Insert "c" and "d" at index 2, deleting 0 elements
letters.splice(2, 0, "c", "d");

console.log(letters); // ["a", "b", "c", "d", "e", "f"]

Insert at the beginning

const nums = [2, 3, 4];
nums.splice(0, 0, 1);
console.log(nums); // [1, 2, 3, 4]
// (For this specific case, unshift(1) also works)

Insert at the end

const nums = [1, 2, 3];
nums.splice(nums.length, 0, 4, 5);
console.log(nums); // [1, 2, 3, 4, 5]
// (For this specific case, push(4, 5) also works)

7. Splice for replacement

Delete some elements and insert new ones in the same call:

const days = ["Mon", "Tue", "WRONG", "WRONG", "Fri"];

// Replace 2 elements at index 2 with "Wed" and "Thu"
days.splice(2, 2, "Wed", "Thu");

console.log(days); // ["Mon", "Tue", "Wed", "Thu", "Fri"]

Replace one element

const scores = [85, 42, 93, 67];
scores.splice(1, 1, 78); // replace index 1 (42) with 78

console.log(scores); // [85, 78, 93, 67]

8. Return value of splice

splice always returns an array of the deleted elements:

const arr = [10, 20, 30, 40, 50];

const del1 = arr.splice(1, 2);
console.log(del1); // [20, 30]

const del2 = arr.splice(1, 0, 99);
console.log(del2); // []  ← nothing was deleted

console.log(arr);  // [10, 99, 40, 50]

9. Critical difference: slice vs splice

Featureslice()splice()
Mutates original?No (safe)Yes (dangerous)
ReturnsNew array (extracted portion)Array of deleted elements
Parameters(start, end) — end exclusive(start, deleteCount, ...items)
Can insert?NoYes
Can delete?No (just excludes from copy)Yes
Naming mnemonicslice = copy extractsplice = place and cut elements

Visual comparison

const arr = [1, 2, 3, 4, 5];

// slice: non-destructive read
arr.slice(1, 3);    // returns [2, 3], arr is still [1, 2, 3, 4, 5]

// splice: destructive modification
arr.splice(1, 2);   // returns [2, 3], arr is now [1, 4, 5]

10. Immutable patterns using slice (instead of splice)

In React and functional code, you often need to "splice" without mutation. Use slice + spread:

Remove element at index (immutable)

function removeAt(arr, index) {
  return [...arr.slice(0, index), ...arr.slice(index + 1)];
}

const nums = [10, 20, 30, 40];
const result = removeAt(nums, 1);
console.log(result); // [10, 30, 40]
console.log(nums);   // [10, 20, 30, 40] ← unchanged

Insert element at index (immutable)

function insertAt(arr, index, ...items) {
  return [...arr.slice(0, index), ...items, ...arr.slice(index)];
}

const nums = [10, 20, 40];
const result = insertAt(nums, 2, 30);
console.log(result); // [10, 20, 30, 40]
console.log(nums);   // [10, 20, 40] ← unchanged

Replace element at index (immutable)

function replaceAt(arr, index, newItem) {
  return [...arr.slice(0, index), newItem, ...arr.slice(index + 1)];
}

const colors = ["red", "WRONG", "blue"];
const fixed = replaceAt(colors, 1, "green");
console.log(fixed);  // ["red", "green", "blue"]
console.log(colors); // ["red", "WRONG", "blue"] ← unchanged

11. Real-world examples

Pagination with slice

const allItems = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];
const pageSize = 3;

function getPage(items, page) {
  const start = (page - 1) * pageSize;
  return items.slice(start, start + pageSize);
}

console.log(getPage(allItems, 1)); // ["a", "b", "c"]
console.log(getPage(allItems, 2)); // ["d", "e", "f"]
console.log(getPage(allItems, 3)); // ["g", "h", "i"]
console.log(getPage(allItems, 4)); // ["j"]

Removing items by value with splice

function removeByValue(arr, value) {
  const index = arr.indexOf(value);
  if (index !== -1) {
    arr.splice(index, 1);
  }
  return arr;
}

const tags = ["js", "css", "html", "react"];
removeByValue(tags, "css");
console.log(tags); // ["js", "html", "react"]

Undo with slice (snapshot history)

const history = [];
let state = [1, 2, 3];

// Save snapshot
history.push(state.slice());

// Modify state
state.push(4);

// Undo: restore from history
state = history.pop();
console.log(state); // [1, 2, 3]

Truncate array

// With slice (non-mutating)
const first3 = arr.slice(0, 3);

// With splice (mutating)
arr.splice(3); // removes everything from index 3 onward

12. Common pitfalls

Confusing slice and splice

// Meant to copy, accidentally mutated
const oops = arr.splice(0); // empties arr! returns all elements
// Should have been: arr.slice()

Forgetting splice mutates

const original = [1, 2, 3, 4, 5];
const portion = original.splice(1, 3); // original is now [1, 5]!
// If you needed original intact, use slice(1, 4) instead

Key takeaways

  1. slice(start, end) extracts a portion into a new array — does not mutate.
  2. splice(start, deleteCount, ...items) modifies in place — mutates the original.
  3. slice() with no args = shallow copy of entire array.
  4. Negative indices count from the end in both methods.
  5. splice returns the deleted elements; slice returns the extracted portion.
  6. For immutable updates (React, Redux), combine slice + spread instead of splice.

Explain-It Challenge

Explain without notes:

  1. What is the single most important difference between slice and splice?
  2. How do you remove an element at index 2 from an array without mutating it?
  3. What does arr.splice(1, 0, "x") do — and what does it return?

Navigation: ← 1.22.e — some() and every() · 1.22.g — sort() →