Arrays: creating, reading and updating

Store ordered lists of values in arrays, read items by index, add and remove items, and check what an array contains.

  • Beginner
  • 7 min read
  • Updated 17 Oct 2026

What you will learn

  • Add and remove array items
  • Read items by index
  • Check whether an array contains a value
  • Tell which array methods change the original array

An array is an ordered list of values: quiz questions, products in a basket, lessons in a course. Almost every program works with lists, so arrays are one of the two data structures you will use most, alongside objects. This lesson covers creating arrays, reading and changing items, and adding and removing them.

Creating an array

Write an array as a list of values in square brackets, separated by commas:

JavaScript
const lessons = ["Variables", "Data types", "Operators"];
const scores = [72, 88, 95];
const empty = [];

An array can hold any mix of types, including other arrays and objects, but most arrays hold one kind of thing. A list where every item has the same shape is easier to work with.

JavaScript
const mixed = ["Ada", 36, true, null];
const grid = [
  [1, 2],
  [3, 4],
];

A trailing comma after the last item is allowed and makes adding lines tidier. Arrays are objects, so typeof gives "object"; use Array.isArray() to check for one, as lesson 4 showed.

Reading items by index

Each item has a numbered position called its index, starting from 0:

JavaScript
const lessons = ["Variables", "Data types", "Operators"];

console.log(lessons[0]);
// Variables
console.log(lessons[2]);
// Operators
console.log(lessons[3]);
// undefined

Reading an index that does not exist gives undefined, not an error. That makes typos quiet, so watch for unexpected undefined values.

The length property tells you how many items there are. Because indexes start at 0, the last item is at length - 1:

JavaScript
console.log(lessons.length);
// 3
console.log(lessons[lessons.length - 1]);
// Operators

The at() method is a neater way to read from the end. Negative numbers count backwards:

JavaScript
console.log(lessons.at(-1));
// Operators
console.log(lessons.at(-2));
// Data types

at() is supported in all current browsers and Node.js.

For a nested array, use two sets of brackets: grid[1][0] reads row 1, then item 0, giving 3.

Changing items

Assign to an index to replace an item:

JavaScript
const colours = ["red", "green", "blue"];
colours[1] = "yellow";

console.log(colours);
// ["red", "yellow", "blue"]

This works even though colours is a const. As lesson 3 explained, const stops you pointing the name at a different array, not changing the array's contents.

Avoid assigning to an index far past the end. colours[10] = "pink" creates an array of length 11 with empty slots in between, which behaves oddly with many methods.

Adding and removing at the ends

Four methods add or remove items at the start or end of an array. They all change the original array:

JavaScript
const queue = ["Ada", "Grace"];

queue.push("Linus");      // add to the end
console.log(queue);
// ["Ada", "Grace", "Linus"]

queue.unshift("Tim");     // add to the start
console.log(queue);
// ["Tim", "Ada", "Grace", "Linus"]

const last = queue.pop(); // remove from the end
console.log(last);
// Linus

const first = queue.shift(); // remove from the start
console.log(first);
// Tim

console.log(queue);
// ["Ada", "Grace"]
  • push() and unshift() return the new length. Both accept several items at once: queue.push("a", "b").
  • pop() and shift() return the item they removed, or undefined if the array was empty.

Adding and removing in the middle with splice

splice() removes, inserts or replaces items at any position. Its arguments are the start index, how many items to remove, then any items to insert:

JavaScript
const steps = ["Plan", "Build", "Ship"];

steps.splice(1, 0, "Design");   // at index 1, remove 0, insert "Design"
console.log(steps);
// ["Plan", "Design", "Build", "Ship"]

const removed = steps.splice(2, 1); // at index 2, remove 1
console.log(removed);
// ["Build"]
console.log(steps);
// ["Plan", "Design", "Ship"]

steps.splice(0, 1, "Research");  // replace the item at index 0
console.log(steps);
// ["Research", "Design", "Ship"]

splice() changes the original array and returns an array of the removed items. It is powerful but easy to misread, so add a short comment when its purpose is not obvious.

Copying part of an array with slice

slice(start, end) returns a new array containing part of the original, from start up to but not including end. The original is unchanged:

JavaScript
const lessons = ["Variables", "Data types", "Operators", "Strings"];

console.log(lessons.slice(1, 3));
// ["Data types", "Operators"]
console.log(lessons.slice(-2));
// ["Operators", "Strings"]
console.log(lessons.length);
// 4

slice() with no arguments copies the whole array. The names slice and splice are easy to confuse: remember that splice has an extra letter because it does extra work and changes the array.

Mutating versus non-mutating methods

Some array methods change, or mutate, the original array. Others return a new array or value and leave the original alone. Knowing which is which prevents a whole class of bugs, especially when an array is shared by several parts of your program.

Mutates the originalReturns something new
push, pop, shift, unshiftslice
spliceconcat
sort, reversetoSorted, toReversed, toSpliced
fillwith

The newer methods in the right-hand column, such as toSorted(), return changed copies. They are supported in all current browsers and Node.js 20+:

JavaScript
const original = [3, 1, 2];
const sorted = original.toSorted();

console.log(sorted);
// [1, 2, 3]
console.log(original);
// [3, 1, 2]

Lesson 22 covers sorting properly, and lesson 40 explains why accidental mutation causes bugs.

Joining arrays

concat() joins arrays into a new one:

JavaScript
const frontEnd = ["HTML", "CSS"];
const scripting = ["JavaScript"];

console.log(frontEnd.concat(scripting));
// ["HTML", "CSS", "JavaScript"]

You will often see the spread syntax [...frontEnd, ...scripting] used for the same job. Lesson 23 covers it.

join() turns an array into a string, with a separator of your choice:

JavaScript
console.log(frontEnd.join(" and "));
// HTML and CSS

Finding values

JavaScript
const tags = ["html", "css", "javascript"];

console.log(tags.includes("css"));
// true
console.log(tags.indexOf("javascript"));
// 2
console.log(tags.indexOf("python"));
// -1
  • includes() returns true or false. Use it when you only need to know whether a value is there.
  • indexOf() returns the first index of the value, or -1.

Both compare with strict equality, so [1, 2].includes("1") is false. One difference: includes() can find NaN and indexOf() cannot.

To find an object in an array by one of its properties, such as a quiz question by its id, you need find() or findIndex(), which take a callback. Lesson 22 covers them.

Looping over an array

As lesson 9 showed, for...of is the simplest way to visit every item:

JavaScript
const basket = [4.99, 12.5, 3];
let total = 0;

for (const price of basket) {
  total += price;
}

console.log(total.toFixed(2));
// 20.49

Emptying an array

To clear a let array, assign a new empty array. To clear a const array in place, set its length to 0:

JavaScript
const items = [1, 2, 3];
items.length = 0;
console.log(items);
// []

Summary

  • Arrays are ordered lists written in square brackets, with indexes starting at 0.
  • Read items with array[index] or array.at(-1) for the end; missing indexes give undefined.
  • push, pop, unshift and shift add and remove at the ends; splice works anywhere. All of them change the original.
  • slice, concat, toSorted and similar methods return new arrays and leave the original alone.
  • includes() checks whether a value is present; indexOf() gives its position or -1.
  • Loop over arrays with for...of.

Further reading