Skip to main content

Immutability in functions

Immutability is the principle that data is not changed after it is created, and inside functions it means one rule: do not mutate the arguments, return a new value instead. It is one of the key principles behind pure, predictable functions: if a function changes an array or object it was given, it affects external state and becomes impure.

Theory

TL;DR

  • Immutability means data is not changed after it is created.
  • For functions the rule reads: do not mutate the arguments, return a new structure.
  • Mutating arguments is a side effect: the caller's data changes invisibly.
  • Immutable tools: map, filter, concat, spread for arrays and { ...obj } for objects.
  • Mutable operations avoided in pure functions: push, pop, splice, sort, reverse, direct field assignment.
  • Strings in JavaScript are always immutable, they cannot be changed in place.

Quick example

javascript
// mutable: changes the caller's array function addItemMutable(arr, item) { arr.push(item); return arr; } // immutable: returns a new array function addItem(arr, item) { return [...arr, item]; } const numbers = [1, 2, 3]; console.log(addItem(numbers, 4)); // [1, 2, 3, 4] console.log(numbers); // [1, 2, 3], the source is intact

Mutation versus a new copy

The mutable approach changes what it was given:

javascript
function addItem(arr, item) { arr.push(item); // changes the original array return arr; } const numbers = [1, 2, 3]; const result = addItem(numbers, 4); console.log(numbers); // [1, 2, 3, 4], the source data changed

The immutable version builds a new array and leaves the input exactly as it was:

javascript
function addItem(arr, item) { return [...arr, item]; // creates a new array } const numbers = [1, 2, 3]; const result = addItem(numbers, 4); console.log(numbers); // [1, 2, 3], the source data is preserved console.log(result); // [1, 2, 3, 4]

The function did not change the input, it returned a new copy, and that is immutability.

Immutable and mutable operations

Data typeImmutable way
Arraymap(), filter(), concat(), spread ([...arr])
Object{ ...obj, key: newValue }
StringAlways immutable, a JavaScript string cannot be changed
Data typeMutable operation
------
Arraypush(), pop(), splice(), sort(), reverse()
ObjectDirect assignment obj.key = value

If a mutable operation is genuinely needed, copy first: [...arr].sort() instead of arr.sort().

Why immutability is worth it

  • It keeps functions pure and predictable.
  • It simplifies debugging and testing: the input is the same after the call as before it.
  • It removes side effects, because nothing outside the function changes.
  • It makes parallel work safe, there is no race over shared data.
  • It makes state comparison and rollback easy, for example in React and Redux, where a new reference means "the data changed".
PropertyImmutable function
Changes the input dataNo
Creates new structuresYes
Side effectsNo
PredictabilityHigh
Examplesmap, filter, reduce

Common mistakes

  • Calling sort() or reverse() on a passed array: both change it in place.
  • Treating spread as a deep copy: { ...obj } copies only the top level, nested objects stay shared.
  • Mutating an argument and returning it, assuming nobody outside will notice: the caller holds the very same reference.
  • Confusing const with immutability: const forbids reassigning the variable, it does not stop you changing the contents of an array or object.
  • Copying on every step inside a hot loop without measuring the cost: sometimes local mutation of the function's own copy is the right call.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.