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.
concat()
Combines two or more arrays.
console.log([1, 2].concat([3, 4])); // [1, 2, 3, 4]
filter()
Filters elements based on a condition.
console.log([1, 2, 3].filter(x => x > 1)); // [2, 3]
map()
Transforms each element using a function.
console.log([1, 2, 3].map(x => x * 2)); // [2, 4, 6]
flat()
Flattens nested arrays (default depth = 1).
console.log([1, [2, [3]]].flat()); // [1, 2, [3]]
flatMap()
Maps and flattens one level deep.
console.log([1, 2].flatMap(x => [x, x * 2])); // [1, 2, 2, 4]
⚠️ 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]
pop()
Removes the last element.
let arr = [1, 2];
console.log(arr.pop()); // 2
console.log(arr); // [1]
shift()
Removes the first element.
let arr = [1, 2];
arr.shift();
console.log(arr); // [2]
unshift()
Adds elements to the beginning.
let arr = [2];
arr.unshift(1);
console.log(arr); // [1, 2]
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]
reverse()
Reverses array in place.
let arr = [1, 2];
arr.reverse();
console.log(arr); // [2, 1]
sort()
Sorts array in place (lexicographically by default).
let arr = [3, 1, 2];
arr.sort();
console.log(arr); // [1, 2, 3]
fill()
Fills elements with a static value.
let arr = [1, 2, 3];
arr.fill(0, 1);
console.log(arr); // [1, 0, 0]
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.
🔎 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
indexOf()
Returns the first index of the value, or -1.
console.log([1, 2, 3].indexOf(2)); // 1
lastIndexOf()
Returns the last index of the value, or -1.
console.log([1, 2, 1].lastIndexOf(1)); // 2
find()
Finds the first element that matches a condition.
console.log([1, 2, 3].find(x => x > 2)); // 3
findIndex()
Returns the index of the first element that matches.
console.log([1, 2, 3].findIndex(x => x > 2)); // 2
forEach()
Executes a function for each element.
[1, 2].forEach(x => console.log(x)); // Logs 1 and 2
reduce()
Reduces array to a single value (left to right).
console.log([1, 2, 3].reduce((a, b) => a + b)); // 6
reduceRight()
Like reduce() but right to left.
console.log([1, 2, 3].reduceRight((a, b) => a - b)); // -4
some()
Checks if any element passes a test.
console.log([1, 2, 3].some(x => x > 2)); // true
every()
Checks if all elements pass a test.
console.log([1, 2, 3].every(x => x > 0)); // true
join()
Joins elements into a string.
console.log([1, 2, 3].join('-')); // "1-2-3"
toString()
Converts array to a comma-separated string.
console.log([1, 2, 3].toString()); // "1,2,3"
at()
Access element by index (supports negatives).
console.log([1, 2, 3].at(-1)); // 3
🧠 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.