So far each variable has held a single value. But real data comes in lists: products in a cart, students in a class, cities on a delivery route. An array is an ordered list of values stored in one variable. You already looped over one in JavaScript Loops; this lesson shows how to create, read, change and transform JavaScript arrays.
Creating an array and reading items
Write an array with square brackets, separating items with commas. Each item has a position called an index, and counting starts at 0, not 1. So the first item is fruits[0] and the last is at index fruits.length - 1. The newer at() method accepts negative numbers, so fruits.at(-1) is a neat way to get the last item.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Arrays basics</title>
<style>
body { font-family: system-ui, sans-serif; padding: 16px; line-height: 1.5; }
</style>
</head>
<body>
<pre id="out"></pre>
<script>
const fruits = ['Mango', 'Banana', 'Guava'];
fruits.push('Jackfruit'); // add to the end
fruits.unshift('Papaya'); // add to the start
fruits[2] = 'Red banana'; // replace the item at index 2
const removed = fruits.pop(); // remove the last item
document.getElementById('out').textContent =
`Fruits: ${fruits.join(', ')}
Count: ${fruits.length}
First: ${fruits[0]}, last: ${fruits.at(-1)}
Removed: ${removed}
Has Guava? ${fruits.includes('Guava')}
Position of Mango: ${fruits.indexOf('Mango')}`;
</script>
</body>
</html>Notice that fruits is a const, yet we changed its contents. const only stops you from assigning a completely new array to the name; the items inside can still be added, removed and replaced.
Tip: JavaScript arrays can hold any type – numbers, strings, booleans, objects, even other arrays – and can mix them. In practice, keep each array to one kind of thing, such as a list of prices or a list of product objects. That makes it much easier to loop over.
Essential array methods
| Method | What it does | Changes the array? |
|---|---|---|
push(x) / pop() | Add to / remove from the end | Yes |
unshift(x) / shift() | Add to / remove from the start | Yes |
includes(x) | Is x in the array? Returns true or false | No |
indexOf(x) | Position of x, or -1 if not found | No |
slice(start, end) | Copy part of the array (end not included) | No |
splice(start, count) | Remove (and optionally insert) items in place | Yes |
join(sep) | Combine all items into one string | No |
sort() / reverse() | Reorder the items | Yes |
The last column matters. Methods that change (“mutate”) the original array can surprise you if another part of your code is still using it. When you need a changed copy instead, use the non-mutating versions toSorted(), toReversed() and toSpliced(), which all modern browsers support.
Watch out: By default sort() compares items as text, so [100, 25, 3].sort() gives [100, 25, 3] because “1” comes before “2” and “3”. For numbers, pass a compare function: prices.sort((a, b) => a - b) sorts from low to high.
Transforming arrays: map, filter, find and reduce
These four methods take a callback function – usually an arrow function, as you learned in JavaScript Functions – and call it once for every item. They replace most hand-written loops and do not change the original array.
map()creates a new array of the same length by transforming each item, such as adding tax to every price.filter()creates a new array containing only the items for which the callback returnstrue.find()returns the first matching item (orundefinedif none match).reduce()boils the whole array down to a single value, such as a total.forEach()simply runs the callback for each item and returns nothing – useful for side effects like adding elements to the page.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Array methods</title>
<style>
body { font-family: system-ui, sans-serif; padding: 16px; line-height: 1.5; }
</style>
</head>
<body>
<pre id="out"></pre>
<script>
const prices = [250, 1200, 75, 640, 3999];
const withGst = prices.map(p => Math.round(p * 1.18));
const under1000 = prices.filter(p => p < 1000);
const firstBig = prices.find(p => p > 1000);
const total = prices.reduce((sum, p) => sum + p, 0);
const lowToHigh = prices.toSorted((a, b) => a - b);
document.getElementById('out').textContent =
`Original: ${prices.join(', ')}
With 18% GST: ${withGst.join(', ')}
Under 1000: ${under1000.join(', ')}
First > 1000: ${firstBig}
Total: ${total}
Low to high: ${lowToHigh.join(', ')}
Original kept: ${prices.join(', ')}`;
</script>
</body>
</html>reduce() looks tricky at first. Its callback receives an accumulator (here sum) and the current item. Whatever the callback returns becomes the accumulator for the next item. The 0 after the callback is the starting value. Read it as: “start at 0, then for each price, add it to the sum”.
You can also chain these methods, because each one returns a new array: prices.filter(p => p < 1000).map(p => p * 2) first keeps the cheaper items and then doubles them.
Copying and checking JavaScript arrays
Assigning an array to another variable does not copy it – both names point to the same list, so changing one changes the “other”. To make a real (shallow) copy, use the spread syntax [...fruits] or fruits.slice(). Spread is covered in Modern JavaScript (ES6+). To test whether a value is an array, use Array.isArray(value); typeof just says "object".
Arrays become even more useful when each item describes something in detail – a product with a name, price and stock count. For that you need JavaScript Objects, the next lesson.
Further reading
- developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
- developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections
- developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
- developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted
