Arrays
An array is JavaScript's built-in ordered list. It holds a sequence of values — numbers, strings, objects, other arrays, even functions — accessible by a numeric index that starts at 0. Arrays are the workhorse data structure of the language: you'll model rows, lists, queues, stacks, paths, history and just about anything sequential with them.
Creating arrays
The literal form with square brackets is the one you should reach for ninety-nine times out of a hundred.
const empty = [];
const nums = [1, 2, 3];
const mixed = [1, "two", true, null, { id: 4 }, [5, 6]];
// The Array constructor exists, but the literal is clearer.
const fromCtor = new Array(1, 2, 3); // [1, 2, 3]
const sized = new Array(3); // length 3, but EMPTY slots
const filled = Array.from({ length: 3 }, (_, i) => i); // [0, 1, 2]
const of = Array.of(3); // [3] (not "length 3")Indexing and length
Indices start at zero. The length property is one greater than the highest set index — and it is writable, which is one of the language's stranger corners.
const fruits = ["apple", "banana", "cherry"]; fruits[0]; // "apple" fruits[2]; // "cherry" fruits[99]; // undefined (not an error) fruits.length; // 3 fruits[5] = "fig"; // assigning past the end EXTENDS the array fruits.length; // 6 (indices 3 and 4 are holes) fruits.length = 2; // truncates: anything from index 2 onwards is gone fruits; // ["apple", "banana"]
Negative indices do not work the way they do in Python. fruits[-1] is treated as the property "-1" and returns undefined. Use arr.at(-1) instead — see the next page on array methods.
Reading, writing, iterating
const colors = ["red", "green", "blue"];
// Classic index loop
for (let i = 0; i < colors.length; i++) {
console.log(i, colors[i]);
}
// for...of — values
for (const c of colors) {
console.log(c);
}
// entries() — index + value
for (const [i, c] of colors.entries()) {
console.log(i, c);
}0 red 1 green 2 blue
Avoid for...in on arrays. It iterates all enumerable string keys — including ones added to Array.prototype by older libraries — and gives you indices as strings rather than numbers.
Sparse arrays (holes)
A sparse array has gaps — indices that were never assigned. Holes are not the same as undefined: most array methods ignore them, but a few (like Array.from) materialise them as undefined.
const sparse = [1, , 3]; // index 1 is a hole sparse.length; // 3 sparse[1]; // undefined (reading a missing prop) sparse.forEach(v => console.log(v)); // 1, 3 (skips the hole) sparse.map(v => v ?? "?"); // [1, <empty>, 3] Array.from(sparse, v => v ?? "?"); // [1, "?", 3] (no holes)
Arrays are objects
Under the hood an array is an object. The numeric "indices" are really string keys ("0", "1", "2"). That has two consequences worth knowing:
You can attach non-numeric properties to an array, but they do not affect
lengthand most array methods will ignore them. It is almost always a sign you should use a regular object instead.typeof []is"object". UseArray.isArray(value)to test specifically for an array — it works across iframes and is the standard answer.
const list = [10, 20, 30];
list.note = "do not lose this"; // legal but weird
list.length; // 3 (the note doesn't count)
typeof list; // "object"
Array.isArray(list); // true
Array.isArray({ length: 0 }); // false (just an object that looks array-ish)Arrays vs plain objects — when to use what
The two are interchangeable for some tasks; you can store rows in an object keyed by id, or fields in an array of pairs. A small decision table helps:
Use an array when order matters and you mostly iterate or push/pop. Examples: a list of todos, a search result page, a queue of jobs.
Use an object (or a
Map) when lookup by key matters and the order does not. Examples: caching responses by URL, user records keyed by id.Arrays let you use methods like
map,filter,reduce,sort. Plain objects do not — you have to go viaObject.entriesfirst.JSON arrays serialise their elements; JSON objects serialise key/value pairs. The choice flows from the data, not from style.
Copying and the reference trap
Assignment copies a reference, not the array. Two variables can point at the same underlying list.
const a = [1, 2, 3]; const b = a; b.push(4); a; // [1, 2, 3, 4] — same array! const c = [...a]; // shallow copy c.push(5); a; // [1, 2, 3, 4] c; // [1, 2, 3, 4, 5]
[...a] (spread) and a.slice() both make a shallow copy — one level deep. Nested arrays and objects are still shared. For a deep copy, use structuredClone(a) in modern environments.
A quick mental model
An array is an ordered collection accessed by zero-based index.
lengthis writable and shrinks or extends the array.Assigning past the end creates holes — avoid this on purpose.
Arrays are objects, but
Array.isArrayis the right type check.Spread or
slicefor shallow copies;structuredClonefor deep ones.
The next page tours the built-in methods — push, pop, slice, concat, flat and friends — that turn the basic structure above into a productive toolkit.