DEV Community

Manoj
Manoj

Posted on

🚀 Mastering JavaScript Array Methods: Mutating vs Non-Mutating

Arrays are one of the most powerful and frequently used data structures in JavaScript. But with so many methods available, it can be hard to remember which ones mutate the original array and which ones create new arrays or simply return a value.

In this post, we'll break down JavaScript array methods into three clear categories:

  • ✅ Methods that create a new array (non-mutating)
  • ⚠️ Methods that change the original array (mutating)
  • 🔎 Methods that do not modify or return an array (read-only operations)

✅ Non-Mutating: Methods That Return a New Array

These methods do not change the original array. Instead, they return a new array based on the operation performed.

slice()

Returns a shallow copy of part of an array.

const arr = [1, 2, 3, 4];
console.log(arr.slice(1, 3)); // [2, 3]

//It copies from index 1 up to (but not including) index 3.
Enter fullscreen mode Exit fullscreen mode

concat()

Combines two or more arrays.

console.log([1, 2].concat([3, 4])); // [1, 2, 3, 4]
Enter fullscreen mode Exit fullscreen mode

filter()

Filters elements based on a condition.

console.log([1, 2, 3].filter(x => x > 1)); // [2, 3]
Enter fullscreen mode Exit fullscreen mode

map()

Transforms each element using a function.

console.log([1, 2, 3].map(x => x * 2)); // [2, 4, 6]
Enter fullscreen mode Exit fullscreen mode

flat()

Flattens nested arrays (default depth = 1).

console.log([1, [2, [3]]].flat()); // [1, 2, [3]]
Enter fullscreen mode Exit fullscreen mode

flatMap()

Maps and flattens one level deep.

console.log([1, 2].flatMap(x => [x, x * 2])); // [1, 2, 2, 4]
Enter fullscreen mode Exit fullscreen mode

⚠️ Mutating: Methods That Change the Original Array

These methods directly modify the array they are called on.

push()

Adds elements to the end.

let arr = [1];
arr.push(2);
console.log(arr); // [1, 2]
Enter fullscreen mode Exit fullscreen mode

pop()

Removes the last element.

let arr = [1, 2];
console.log(arr.pop()); // 2
console.log(arr); // [1]
Enter fullscreen mode Exit fullscreen mode

shift()

Removes the first element.

let arr = [1, 2];
arr.shift();
console.log(arr); // [2]
Enter fullscreen mode Exit fullscreen mode

unshift()

Adds elements to the beginning.

let arr = [2];
arr.unshift(1);
console.log(arr); // [1, 2]
Enter fullscreen mode Exit fullscreen mode

splice()

Adds/removes elements at a specified index.

let arr = [1, 2, 3];
arr.splice(1, 1); // removes 1 element at index 1
console.log(arr); // [1, 3]
Enter fullscreen mode Exit fullscreen mode

reverse()

Reverses array in place.

let arr = [1, 2];
arr.reverse();
console.log(arr); // [2, 1]
Enter fullscreen mode Exit fullscreen mode

sort()

Sorts array in place (lexicographically by default).

let arr = [3, 1, 2];
arr.sort();
console.log(arr); // [1, 2, 3]
Enter fullscreen mode Exit fullscreen mode

fill()

Fills elements with a static value.

let arr = [1, 2, 3];
arr.fill(0, 1);
console.log(arr); // [1, 0, 0]
Enter fullscreen mode Exit fullscreen mode

copyWithin()

Copies part of the array within itself.

let arr = [1, 2, 3, 4];
arr.copyWithin(1, 2);
console.log(arr); // [1, 3, 4, 4]

//Copies [3, 4] (from index 2 to end) to the (index 1), replacing 2 and 3.
Enter fullscreen mode Exit fullscreen mode

🔎 Read-Only: Methods That Don’t Modify or Return a New Array

These methods don’t mutate or return a new array. Instead, they return other values (like booleans, strings, or numbers).

includes()

Checks if a value exists.

console.log([1, 2, 3].includes(2)); // true
Enter fullscreen mode Exit fullscreen mode

indexOf()

Returns the first index of the value, or -1.

console.log([1, 2, 3].indexOf(2)); // 1
Enter fullscreen mode Exit fullscreen mode

lastIndexOf()

Returns the last index of the value, or -1.

console.log([1, 2, 1].lastIndexOf(1)); // 2
Enter fullscreen mode Exit fullscreen mode

find()

Finds the first element that matches a condition.

console.log([1, 2, 3].find(x => x > 2)); // 3
Enter fullscreen mode Exit fullscreen mode

findIndex()

Returns the index of the first element that matches.

console.log([1, 2, 3].findIndex(x => x > 2)); // 2
Enter fullscreen mode Exit fullscreen mode

forEach()

Executes a function for each element.

[1, 2].forEach(x => console.log(x)); // Logs 1 and 2
Enter fullscreen mode Exit fullscreen mode

reduce()

Reduces array to a single value (left to right).

console.log([1, 2, 3].reduce((a, b) => a + b)); // 6
Enter fullscreen mode Exit fullscreen mode

reduceRight()

Like reduce() but right to left.

console.log([1, 2, 3].reduceRight((a, b) => a - b)); // -4
Enter fullscreen mode Exit fullscreen mode

some()

Checks if any element passes a test.

console.log([1, 2, 3].some(x => x > 2)); // true
Enter fullscreen mode Exit fullscreen mode

every()

Checks if all elements pass a test.

console.log([1, 2, 3].every(x => x > 0)); // true
Enter fullscreen mode Exit fullscreen mode

join()

Joins elements into a string.

console.log([1, 2, 3].join('-')); // "1-2-3"
Enter fullscreen mode Exit fullscreen mode

toString()

Converts array to a comma-separated string.

console.log([1, 2, 3].toString()); // "1,2,3"
Enter fullscreen mode Exit fullscreen mode

at()

Access element by index (supports negatives).

console.log([1, 2, 3].at(-1)); // 3
Enter fullscreen mode Exit fullscreen mode

🧠 Final Thoughts

Knowing which array methods mutate the original array and which don’t can save you from unexpected bugs—especially when working with functional programming or immutability in frameworks like React.

Next time you’re working with arrays, consider:

❓ Do I need to modify the original array?

✅ Do I want a new array returned?

🔍 Do I just need to check or search something?

Understanding these differences will make your code more predictable, clean, and bug-free.

If you found this helpful, consider bookmarking, sharing, or giving a ❤️.
Happy coding! 💻✨

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.