Array Methods You Must Know: push, pop, map, filter, reduce, forEach

Arrays are everywhere in JavaScript — a list of users, a shopping cart’s items, search results, form fields. And a small handful of built-in array methods handle the overwhelming majority of what you’ll ever need to do with them. This guide walks through six of the most essential ones, each with a simple before-and-after example you can try directly in your browser console.
push() and pop()
push() adds an item to the end of an array. pop() removes the last item from an array.
let fruits = ["apple", "banana"];
fruits.push("mango");
console.log(fruits); // ["apple", "banana", "mango"]
fruits.pop();
console.log(fruits); // ["apple", "banana"]Before: ["apple", "banana"] After push("mango"): ["apple", "banana", "mango"] After pop(): ["apple", "banana"]
Both methods modify the array directly (they mutate it) — notice fruits itself changed, rather than a new array being created.
shift() and unshift()
unshift() adds an item to the beginning of an array. shift() removes the first item from an array.
let queue = ["Aarav", "Priya"];
queue.unshift("Meera");
console.log(queue); // ["Meera", "Aarav", "Priya"]
queue.shift();
console.log(queue); // ["Aarav", "Priya"]Before: ["Aarav", "Priya"] After unshift("Meera")): ["Meera", "Aarav", "Priya"] After shift(): ["Aarav", "Priya"]
A simple way to remember the difference: push/pop work at the end of the array; shift/unshift work at the beginning.
map()
map() creates a brand-new array by transforming every item in the original array, using a function you provide.
const numbers = [1, 2, 3, 4];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8]
console.log(numbers); // [1, 2, 3, 4] — the original is untouchedBefore: [1, 2, 3, 4] After map(num => num * 2): [2, 4, 6, 8]
Unlike push() or pop(), map() doesn't modify the original array. Instead, it returns a new array with the same length. For ordinary (non-sparse) arrays, each element is transformed by the callback function.

map() vs a traditional for loop
// Traditional for loop
const doubled1 = [];
for (let i = 0; i < numbers.length; i++) {
doubled1.push(numbers[i] * 2);
}
// map()
const doubled2 = numbers.map(num => num * 2);Both produce the same result — but map() states the intent directly ("transform every item") without the bookkeeping of manually managing an index and a separate empty array to push into.
Technical Note: The examples in this article use ordinary (non-sparse) arrays. In these arrays, map() calls the callback once for each element. Sparse arrays preserve their empty slots, so the callback isn't invoked for those positions.
filter()
filter() creates a new array containing only the items that pass a test you provide — items where your function returns true.
const numbers = [4, 9, 15, 2, 22];
const bigNumbers = numbers.filter(num => num > 10);
console.log(bigNumbers); // [15, 22]
console.log(numbers); // [4, 9, 15, 2, 22] — unchangedBefore: [4, 9, 15, 2, 22] After filter(num => num > 10): [15, 22]
Just like map(), filter() never modifies the original array — it always returns a new one, though this time possibly shorter, since only the items passing the test make it through.

filter() vs a traditional for loop
// Traditional for loop
const bigNumbers1 = [];
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] > 10) {
bigNumbers1.push(numbers[i]);
}
}
// filter()
const bigNumbers2 = numbers.filter(num => num > 10);Again, both work — but filter() reads almost like plain English: "give me the numbers greater than 10," without the surrounding loop scaffolding.
reduce() (Basic Explanation)
reduce() takes an entire array and boils it down to a single value — most commonly used to calculate a total.
const numbers = [1, 2, 3, 4];
const total = numbers.reduce((sum, current) => sum + current, 0);
console.log(total); // 10Here’s the simplest way to think about it: reduce() keeps a running value (called the accumulator, sum in this example) and updates it once for every item in the array, finally handing back just that one final value.
sum— the running total so farcurrent— the array item being processed right now0— the starting value forsum, before processing any items

reduce() is genuinely one of the trickier methods to get comfortable with at first — a good way to build intuition is simply tracing through, item by item, exactly how the accumulator changes on each step, the way the diagram above does.
forEach()
forEach() runs a function once for every item in an array — but unlike map() or filter(), it doesn't return a new array at all. It's purely for performing an action per item, like logging or updating something outside the array.
const fruits = ["apple", "banana", "mango"];
fruits.forEach(fruit => {
console.log(`I have a ${fruit}`);
});
// I have a apple
// I have a banana
// I have a mangoforEach() vs a traditional for loop
// Traditional for loop
for (let i = 0; i < fruits.length; i++) {
console.log(`I have a ${fruits[i]}`);
}
// forEach()
fruits.forEach(fruit => {
console.log(`I have a ${fruit}`);
});forEach() removes the need to manually manage an index variable — but remember, it doesn't build a new array like map() does. If you need a transformed array back, map() is the right tool; if you just need to do something for each item, forEach() fits better.
Quick Reference


Practice Assignment
Try this directly in your browser console — it uses every method covered above, in sequence:
// 1. Create an array of numbers
const numbers = [3, 6, 9, 12];
// 2. Use map() to double each number
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [6, 12, 18, 24]
// 3. Use filter() to get numbers greater than 10
const filtered = doubled.filter(num => num > 10);
console.log(filtered); // [12, 18, 24]
// 4. Use reduce() to calculate the total sum
const total = filtered.reduce((sum, current) => sum + current, 0);
console.log(total); // 54Try changing the starting numbers, the doubling logic, or the filter threshold, and predict the output before running it — that habit alone is one of the fastest ways to build real intuition for how these methods actually behave.
Final Takeaway
These six methods cover the overwhelming majority of everyday array work in JavaScript. push/pop/shift/unshift change an array directly, adding or removing from either end. map() and filter() both return new arrays — one transforms every item, the other keeps only the ones that pass a test. reduce() boils an entire array down to one value. And forEach() simply runs something for every item, without building anything new. Once these six feel natural, reading — and writing — real-world JavaScript array code becomes dramatically easier.
Frequently Asked Questions
Why do map() and filter() return new arrays instead of changing the original?
> This is intentional — it keeps your original data safe from accidental changes, and lets you chain multiple operations together clearly, since each step’s input and output are both predictable, unmodified arrays.
Is reduce() always used for summing numbers?
> No — summing is the simplest example, but reduce() can build up any kind of single result: concatenating strings, building an object, counting occurrences, or flattening nested arrays. Summing is just the easiest place to start.
Should I always use map()/filter() instead of a for loop?
> Not always — for straightforward transformations and filtering, they’re generally more readable. A traditional loop can still make sense for more complex logic (like needing to break out early), where forcing it into map()/filter() would actually hurt readability.
What happens if I forget the starting value in reduce()?
> Without a starting value, reduce() uses the array's first item as the initial accumulator and starts processing from the second item — which can produce unexpected results for empty arrays or when you specifically wanted the accumulator to start at zero. Providing an explicit starting value is generally the safer habit.
Originally published by Mr Madhukar
Read the complete article on Medium with full formatting & reader responses.