Immutable Array Patterns (ES2023)
MedImmutable array operations create new arrays instead of modifying the original. This is essential for functional programming, React state updates, and avoiding side effects. ES2023 added new immutable methods: toSorted(), toReversed(), toSpliced(), and with(). Learn patterns for adding, removing, and updating elements immutably.
Interactive Visualization
mutation Methods
1
2
3
Key Points
- Immutable operations return new arrays
- Spread operator [...arr] for shallow copies
- ES2023: toSorted(), toReversed(), toSpliced(), with()
- filter() for removing elements immutably
- map() for updating elements immutably
- slice() and spread for inserting elements
Code Examples
ES2023 Immutable Methods
const arr = [3, 1, 4, 1, 5]; // toSorted - immutable sort const sorted = arr.toSorted((a, b) => a - b); console.log(sorted); // [1, 1, 3, 4, 5] console.log(arr); // [3, 1, 4, 1, 5] - unchanged! // toReversed - immutable reverse const reversed = arr.toReversed(); console.log(reversed); // [5, 1, 4, 1, 3] // toSpliced - immutable splice const spliced = arr.toSpliced(1, 2, 'a', 'b'); console.log(spliced); // [3, 'a', 'b', 1, 5] // with - replace element at index const replaced = arr.with(2, 'x'); console.log(replaced); // [3, 1, 'x', 1, 5]
ES2023 adds immutable versions of mutating methods. All return new arrays.
Add Elements Immutably
const arr = [1, 2, 3]; // Add to end const addEnd = [...arr, 4]; console.log(addEnd); // [1, 2, 3, 4] // Add to beginning const addStart = [0, ...arr]; console.log(addStart); // [0, 1, 2, 3] // Insert at index const insertAt2 = [...arr.slice(0, 2), 'x', ...arr.slice(2)]; console.log(insertAt2); // [1, 2, 'x', 3] // Or use toSpliced (ES2023) const insertES2023 = arr.toSpliced(2, 0, 'x'); console.log(insertES2023); // [1, 2, 'x', 3]
Use spread with slice for immutable insertion at any position.
Remove Elements Immutably
const arr = [1, 2, 3, 4, 5]; // Remove by value const without3 = arr.filter(x => x !== 3); console.log(without3); // [1, 2, 4, 5] // Remove by index const removeAt2 = [...arr.slice(0, 2), ...arr.slice(3)]; console.log(removeAt2); // [1, 2, 4, 5] // Remove first const [, ...rest] = arr; console.log(rest); // [2, 3, 4, 5] // Remove last const withoutLast = arr.slice(0, -1); console.log(withoutLast); // [1, 2, 3, 4] // Or use toSpliced const removedES2023 = arr.toSpliced(2, 1); // Remove 1 element at index 2 console.log(removedES2023); // [1, 2, 4, 5]
Use filter to remove by value, slice/spread to remove by index.
Update Elements Immutably
const users = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Carol' } ]; // Update one element const updated = users.map(user => user.id === 2 ? { ...user, name: 'Bobby' } // New object for changed item : user // Unchanged reference ); console.log(updated[1]); // { id: 2, name: 'Bobby' } console.log(users[1]); // { id: 2, name: 'Bob' } - unchanged! // Or use with() for simple arrays const nums = [1, 2, 3, 4]; const newNums = nums.with(1, 99); console.log(newNums); // [1, 99, 3, 4]
Use map to update elements, spreading to create new objects. with() for simple value replacement.
Common Mistakes
- Using mutating methods when immutability is needed (React state)
- Creating deep copies when shallow is sufficient
- Not realizing spread is shallow (nested objects still shared)
- Using JSON.parse/stringify for deep copy (loses functions, dates)
Interview Tips
- Know ES2023 immutable methods
- Understand shallow vs deep copy
- Know patterns for add/remove/update immutably
- Know structuredClone() for deep copy