Mutator methods change the array in place. Watch their return values: push() gives the new length, splice() the removed elements, and sort() or fill() the very same array object, not a copy.
| Method | Returns | Mutates? |
|---|---|---|
| push(), unshift() | New length | Yes |
| pop(), shift() | Removed element | Yes |
| splice(start, count, ...add) | Removed elements | Yes |
| fill(), copyWithin() | The same array | Yes |
| sort(compareFn?), reverse() | The same array | Yes |
const a = [1, 2, 3];
console.log(a.push(4, 5), a.pop(), a.unshift(0), a.shift(), a); // [1, 2, 3, 4]
console.log(a.splice(1, 2, 'x', 'y', 'z'), a); // remove 2 items at 1, insert 3
console.log(a.fill(0, -2), [1, 2, 3, 4, 5].copyWithin(0, 3));
console.log([10, 9, 1, 100].sort(), [10, 9, 1, 100].sort((m, n) => m - n));5 5 5 0 [ 1, 2, 3, 4 ] [ 2, 3 ] [ 1, 'x', 'y', 'z', 4 ] [ 1, 'x', 'y', 0, 0 ] [ 4, 5, 3, 4, 5 ] [ 1, 10, 100, 9 ] [ 1, 9, 10, 100 ]
With no compare function, sort() compares elements as strings, so 100 sorts before 9: pass (m, n) => m - n for numbers or (m, n) => m.localeCompare(n) for text. The sort has been guaranteed stable since ES2019. Pitfalls:
sort(() => Math.random() - 0.5) is a biased shuffle: in 600,000 trials on Node.js 25.8 2,131 , [1, 2, 3] came out 123 twice as often as 321. Use Fisher-Yates (Destructuring Assignment).
Array(3).fill({}) puts one shared object in every slot; use Array.from({ length: 3 }, () => ({})).
a.push(...b) throws RangeError on Node.js 25.8 when b holds 150,000 items; loop or use concat() instead.