Mutation in JavaScript: changing a value in place, and what it breaks

A mutation modifies an existing object or array instead of creating a new one. Useful, fast, and responsible for bugs that are hard to locate.
3 min read
Believemy logo

Adding an item to an array looks harmless. If that array was handed to three parts of the program, all three see the change, without asking for it.

That is what mutation does: it produces no new value, it modifies the one that already exists, for everyone holding it.


Definition

A mutation is a change applied in place to an existing value. Only objects and arrays can mutate, because they are handled by reference. Numbers and strings never change.

JAVASCRIPT
const original = [3, 1, 2];
const assumedCopy = original;

assumedCopy.push(4);
console.log(original); // [ 3, 1, 2, 4 ]

const realCopy = [...original];
realCopy.push(5);
console.log(original.length); // 4
console.log(realCopy.length); // 5

assumedCopy is not a copy: it is a second name for the same array. Spread (...) builds a real, independent one.


Array methods, sorted into two camps

The confusion comes from the two families looking alike when written. This two-column table separates them.

Modify the arrayReturn a new array
push, pop, shift, unshiftconcat, slice
splicefilter, toSpliced
sorttoSorted
reversetoReversed

The three methods starting with to were added to the language precisely to offer a version that does not mutate. See Array.sort() and slice() for the details of each.


When mutating is still the right call

  • On a local value. An array built inside a function and never handed out risks nothing.
  • On very large volumes. Copying a million items at every step eventually shows.
  • Inside an explicit accumulator. A Array.reduce() filling its own object stays readable and safe.
Good to know

The practical rule fits in one sentence: mutate what you created, never what you received. A modified argument is a Side effect the caller never saw coming.


Frequently asked questions

Question

How do I track down a stray mutation?

The classic symptom is a value that changes while no visible line touches it. Freezing the structure with Object.freeze() during development surfaces the culprit, since the change then throws instead of slipping through. See Immutability for the limits of freezing.


Question

Can a string mutate?

No. Every String method returns a new string, including the ones that look like they transform the original. Writing text.toUpperCase() without capturing the result changes nothing. The same holds for numbers and booleans.


Question

Why does my sort modify the original array?

Because sort() sorts in place and returns the same array, not a copy. It is the most common trap of the family, especially when the result is assigned to a new variable, which creates the illusion of a copy. Use toSorted(), or sort a copy obtained with [...list].

Related terms

Discover our javaScript glossary

Every word of JavaScript explained simply: keywords, built-in objects, methods, errors and concepts. Clear definitions and examples that actually run, to learn and to troubleshoot.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.