JavaScript
Copying array methods and mutating array methods

Copying array methods and mutating array methods

Some methods do not mutate the existing array that the method was called on, but instead return a new array. The copy always happens shallowly (opens in a new tab) — the method never copies anything beyond the initially created array.

Other methods mutate the array that the method was called on, in which case their return value differs depending on the method: sometimes a reference to the same array, sometimes the length of the new array.

The following methods create new arrays by accessing this.constructor[Symbol.species] (opens in a new tab) to determine the constructor to use:

  • concat()
  • filter()
  • flat()
  • flatMap()
  • map()
  • slice()
  • splice() (to construct the array of removed elements that's returned)

The following methods always create new arrays with the Array base constructor:

  • toReversed()
  • toSorted()
  • toSpliced()
  • with()

The following table lists the methods that mutate the original array, and the corresponding non-mutating alternative:

Mutating methodNon-mutating alternative
copyWithin()No one-method alternative
fill()No one-method alternative
pop()slice(0, -1)
push(v1, v2)concat([v1, v2])
reverse()toReversed()
shift()slice(1)
sort()toSorted()
splice()toSpliced()
unshift(v1, v2)toSpliced(0, 0, v1, v2)

An easy way to change a mutating method into a non-mutating alternative is to use the spread syntax (opens in a new tab) or slice() to create a copy first:

arr.copyWithin(0, 1, 2); // mutates arr
const arr2 = arr.slice().copyWithin(0, 1, 2); // does not mutate arr
const arr3 = [...arr].copyWithin(0, 1, 2); // does not mutate arr

Reference