ReviseAlgo Logo

Arrays & Iterables

Mutating Methods

Master JavaScript mutating array methods. Compare push, pop, shift, unshift, splice, sort, and reverse in terms of performance and behavior.

Last Updated: July 15, 2026 10 min read

1. Introduction

JavaScript arrays have built-in methods on their prototype. Mutating Methods modify the original array directly in place, rather than returning a new array copy.

2. Why It Matters

Mutating methods are highly performant because they avoid creating new arrays in memory. However, modifying arrays directly in shared state environments (like React state or Redux stores) can prevent components from re-rendering and lead to bugs.

3. Real-World Analogy

Think of a Magnetic Message Board:

  • Mutating Method: Rearranging, adding, or removing magnetic letters directly on the board. You modify the original layout in place, and everyone looking at the board sees the updates immediately.
  • Non-Mutating Method: Taking a photo of the message board, editing the photo on your phone, and showing the edited image. The original letters on the board remain unchanged.

4. Core Mutating Methods

Let's explore the common mutating methods:

1. Stack & Queue Operations:

  • push(...items): Adds elements to the end of the array. Returns the new array length. (O(1) complexity)
  • pop(): Removes and returns the last element. (O(1) complexity)
  • unshift(...items): Adds elements to the beginning of the array. Requires shifting all subsequent elements, which is a slow operation. (O(N) complexity)
  • shift(): Removes and returns the first element. (O(N) complexity)

2. Splice, Sort & Reverse:

  • splice(start, deleteCount, ...items): Adds or removes elements anywhere in the array. Returns an array containing the deleted elements.
  • sort(compareFunction): Sorts the elements of the array in place. By default, it converts values to strings and compares their UTF-16 code units.
  • reverse(): Reverses the order of the elements in place.

5. Comparison of Mutating Operations

Method Time Complexity Return Value Mutates Source?
push / pop O(1) New length / Removed item Yes
unshift / shift O(N) New length / Removed item Yes
splice O(N) Array of deleted items Yes
sort O(N log N) Reference to sorted array Yes

6. Practical Example

This script demonstrates how sorting numbers without a custom compare function can produce unexpected results, and how to fix it:

7. Common Mistakes

  • Sorting numbers without a compare function: The default behavior converts numbers to strings, leading to alphabetical sorting bugs (e.g. 10 sorted before 2).
  • Mutating state arrays directly in React: Modifying state arrays using mutating methods (like push or splice) does not trigger component re-renders. Use non-mutating copy alternatives instead.

8. Quick Quiz

Q1: What is the time complexity of adding an element to the beginning of an array using unshift?

A) O(1)

B) O(N)

Answer: B — unshift() requires shifting all subsequent elements to new index positions, resulting in O(N) complexity.

9. Scenario-Based Challenge

The Sorted Scoreboard Queue:

You maintain an active scoreboard array: scores. When a new score arrives, append it, sort the scoreboard in descending order, and truncate the list to keep only the top 5 scores. Write a function that performs this operation in place using mutating methods.

10. Debugging Exercise

Identify and fix the sorting bug in this array configuration update:

const configs = [
  { id: 1, priority: 'high' },
  { id: 2, priority: 'low' }
];

// Objective: Sort configs in place by priorities configs.sort((a, b) => a.priority > b.priority); // bug: compare function returns boolean! console.log(configs); // sorting behavior is inconsistent across browsers! Why?

View Solution

Diagnosis: The compare function must return a number (negative, zero, or positive). Returning a boolean value causes inconsistent sorting behaviors because the engine cannot determine element order correctly.

Fix: Return a numeric value based on string comparison:

configs.sort((a, b) => a.priority.localeCompare(b.priority));

11. Interview Questions

🟢 Q1: Contrast push/pop with shift/unshift in terms of execution speed and memory shift complexity.

Answer:
push and pop operate at the end of the array. Since subsequent elements don't need to change indexes, these operations run in O(1) constant time.
shift and unshift operate at the beginning of the array. This requires shifting all subsequent elements to new index positions, resulting in O(N) linear time complexity.

12. Production Considerations

  • Non-Mutating Alternatives: If you are working in environments that require immutability (like React), use modern non-mutating copy alternatives introduced in ES2023, such as toSorted(), toReversed(), and toSpliced().