Topic 5.1
Creating and Reading Arrays
In one line
An array is an ordered list of values; you create one with square brackets, read items by their position number (the index, starting at 0), get the count from length, and build arrays from other things with Array.from and Array.of.
Think of it like this
A row of numbered lockers at a swimming pool. The row has one name ("the blue lockers"), and each locker has a number painted on the door, starting at 0. To get your bag you say "locker 2", not "the third one from the left". The sign at the end says how many lockers there are. An array is that row: one name, numbered slots, and a count.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Array
- An ordered list of values stored under one name.
- Element (item)
- One value inside an array.
- Index
- The position number of an element. The first one is 0, not 1.
- length
- The number of slots in the array: one more than the last index.
- Array literal
- An array written directly in code with square brackets, like
[1, 2, 3]. - Sparse array
- An array with holes: empty slots that hold no value at all.
- Iterable
- Something you can loop over with
for...of, such as an array, a string, aSetor aMap. - Array-like
- An object that has a
lengthand numbered keys but isn't a real array, such as aNodeList. - Reference
- What a variable really holds for an array: a pointer to the one array in memory, not a copy.
Step by step
01Make an array
Square brackets, items separated by commas. A comma after the last item (a trailing comma) is allowed and makes adding lines easier.
const pets = [
"cat",
"dog",
"fish",
];
console.log(pets.length); // 302Read by index
Counting starts at 0, so three items have the indexes 0, 1 and 2. The last index is always length - 1.
03Read from the end
pets[pets.length - 1] works everywhere. pets.at(-1) says the same thing more clearly.
console.log(pets[pets.length - 1]); // fish
console.log(pets.at(-1)); // fish
console.log(pets[-1]); // undefined04Change an item
Assigning to an index replaces that slot. The variable is const, but the array it points to can still change.
pets[1] = "parrot";
console.log(pets); // [ 'cat', 'parrot', 'fish' ]05Build an array from something else
Array.from turns strings, sets and page lists into real arrays, so you can use every array method on them. Pass a function as the second argument to change each item as it's copied.
Array.from("abc"); // [ 'a', 'b', 'c' ]
Array.from({ length: 3 }, (_, i) => i + 1); // [ 1, 2, 3 ]
Array.of(3); // [ 3 ]Try it yourself
- 1
Read from the end
In the first example, predict what
fruits.at(-2)andfruits.at(-4)print. Add both lines and run. - 2
Make a times table
In the second example, change the
Array.from({ length: 4 }, ...)line so it prints[ 7, 14, 21, 28, 35 ]. You need to change the length and the formula (rememberistarts at 0). - 3
Grow by writing length
In the third example, add
nums.length = 7;at the end and lognums. Predict how many<empty>slots you'll see.
Code & diagrams
`at()` is ES2022; everything else here has worked since the first versions of JavaScript. The page uses an `<ol>`, which numbers from 1, while the indexes start at 0.
Preview
Console
Nothing logged yet.Expected console output
[ 'apple', 'banana', 'cherry' ]
3
apple cherry
undefined
cherry
cherry
undefinedHectal's console shows each hole as `<empty>`. Chrome's DevTools shows `[empty × 3]` and Node.js shows `[ <3 empty items> ]`: same thing.
Preview
Console
Nothing logged yet.Expected console output
[ 7 ]
7
[ <empty>, <empty>, <empty> ]
[ 'h', 'i', '!' ]
[ 0, 10, 20, 30 ]
[ 3, 1 ]
false true
[ 'Tea', 'Coffee' ]Setting `length` smaller deletes items for good. Writing past the end leaves holes. `const` only protects the variable, not the array's contents.
Console
(nothing was printed)Expected console output
[ 1, 2 ]
[ 1, 2, <empty>, <empty>, 9 ] 5
object true
[ 'allowed' ]Break it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Off by one at the end
Loop with i <= fruits.length instead of i < fruits.length.
Break #2
Array(3) instead of [3]
Write const ids = new Array(3); meaning "an array containing 3", then console.log(ids[0]);.
Myth vs fact
Myth
arr[-1] gives the last element, like in Python.
Fact
In JavaScript it is undefined: -1 is looked up as an ordinary property name. Use arr.at(-1) or arr[arr.length - 1].
Myth
A const array can't be changed.
Fact
const means the variable always points at the same array. You can still add, remove and replace items inside it. To stop changes to the contents, use Object.freeze(arr) (Phase 6).
Myth
Reading outside the array throws an error.
Fact
It returns undefined, quietly. That's why off-by-one bugs in JavaScript often don't crash; they show undefined somewhere instead.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
Engines like V8 store arrays in fast internal forms called elements kinds: packed small integers, packed doubles, or general values. Mixing types or making holes moves an array to a slower kind, and it never moves back.
new Array(1000)starts holey; building withpushorArray.fromkeeps it packed. - ▸
Array indexes are really property keys, converted to strings:
arr["1"]andarr[1]are the same slot. Only keys that are whole numbers from 0 to 2³² − 2 count as indexes and affectlength;arr[-1] = "x"creates a normal property thatlengthignores. - ▸
Array.fromworks on any iterable, so it understands Unicode properly:Array.from("👍🏽").lengthcounts code points, while"👍🏽".lengthcounts UTF-16 code units. (Phase 1 covers strings and Unicode.) - ▸
The maximum array length is 2³² − 1 (4,294,967,295). Typed arrays (
Uint8Array,Float64Array) are a separate family with a fixed length and one numeric type, used for binary data and graphics.
Remember this
- 1
An array is a value that holds an ordered list of other values. You write one with square brackets and commas:
const scores = [90, 75, 60];. This is called an array literal (a value written directly in the code). The values inside are called elements or items, and they can be any type, even mixed:[1, "two", true, null, [3]]. In practice, keep one kind of thing per array; mixed arrays are harder to work with. - 2
Each element has an index: its position number, starting at 0.
scores[0]is90,scores[1]is75. Reading an index that doesn't exist does not throw an error:scores[10]isundefined. Thelengthproperty is the number of slots, so the last element is atscores[length - 1]. Negative numbers in brackets don't count from the end:scores[-1]isundefined, because-1is treated as an ordinary property name. - 3
at(index)(ES2022) reads an element and does accept negative numbers:scores.at(-1)is the last item,scores.at(-2)the one before. It's the clean way to read from the end. For positive numbers it behaves like brackets. - 4
lengthis not just a count you read; you can write it. Settingarr.length = 2cuts the array down to two elements (the rest are deleted). Writing to an index past the end, likearr[5] = "x"on a 3-item array, makes the array longer and leaves holes: empty slots that hold nothing at all (not evenundefined). Arrays with holes are called sparse; avoid creating them. - 5
Array.from(thing, mapFn?)(ES2015) builds a real array from anything iterable (something you can loop over, like a string or aSet) or array-like (an object withlengthand numbered keys, like theNodeListthatdocument.querySelectorAllreturns). The optional second argument changes each item on the way in:Array.from({ length: 3 }, (_, i) => i * 2)gives[0, 2, 4].Array.of(7)(ES2015) makes[7]; it exists becauseArray(7)andnew Array(7)mean something else: an empty array with length 7 (seven holes). - 6
Arrays are a special kind of object (Phase 6):
typeof [] === "object". To check whether a value really is an array, useArray.isArray(value). And because arrays are objects, a variable holds a reference to the array (an arrow pointing at it), not the array itself.conststops you pointing the variable at a different array, but you can still change the items inside:const list = []; list[0] = 1;is allowed.
Explain it without notes
Why do arrays start at index 0, and how do you safely read the last element?
What is the difference between Array(3), Array.of(3) and [3]?
What does Array.from accept, and why is it useful with querySelectorAll?
How do you check whether a value is an array, and why doesn't typeof work?
Practice
Create an array of five weekdays. Print the first day, the last day using at, and the number of days.
Use Array.from to build an array of the squares of 1 to 5: [ 1, 4, 9, 16, 25 ].
Given const word = "level";, make an array of its letters and print the middle letter using length.
Trade-offs
- ↔
arr.at(-1)reads better thanarr[arr.length - 1], but needs a 2022-or-later browser; both are equally fast. - ↔
Array.from(nodes)and[...nodes]do the same for iterables;Array.fromalso handles array-like objects without an iterator and can map in the same pass.
Done when you can
I can create an array and read any element by its index.
I can read the last element with
at(-1)orlength - 1.I know that reading a missing index gives
undefined, not an error.I can turn a string, a Set or a NodeList into an array with
Array.from.I can explain why
Array(3)is not[3].I check for arrays with
Array.isArray.