completefrontend
Open lab My progress
THE JAVASCRIPT FIELD GUIDE

Array basics

Create JavaScript arrays, read indexes with at() and length, change both ends with push, pop, shift, and unshift, and avoid sparse-array surprises.

By the end you can
  • 01
    Make the array you meanMake arrays with square brackets, and know why new Array(3) gives three empty positions instead of the number 3.
  • 02
    Read by positionRead elements with indexes that start at 0, read the last one with at(-1), and use length to make an array shorter.
  • 03
    Change an array on purposePredict what push, pop, shift, and unshift do and return, and spot extra properties and holes.

Arrays are ordered lists

An array is a list of values kept in order. You can read any value by its position. You can also pass the whole list around under one name. Many everyday things are lists in order: the items in a shopping cart, the results of a search, and the answers in a quiz.

Definition

An array is a special kind of object that keeps values in order. Each value in the list is called an element. Each element sits at a numbered position, called an index. The first index is 0.

An array also has a length property. It is one more than the highest index. For a normal list, that is the number of elements.

Read a shopping cartPop out in the code editor (opens in a new tab)JavaScript
const cart = ["tea", "bread"];
console.log(cart[0]);
console.log(cart.length);

Line 1 makes an array named cart with two elements. Line 2 reads index 0, the first position, so it prints tea. Line 3 reads the array's length, so it prints 2. The elements stay in their order, and the whole list has one name.

A tag named cart points at a row of two cards. The tea card is at index 0. The bread card is at index 1. The length is 2.cart"tea""bread"index 0index 1length: 2
The name cart points at one row of values. The first position is index 0, the next is index 1. There are two values, so cart.length is 2.
Real-life analogyA numbered row of lockers

Picture a hallway with a row of lockers. Each locker has a number painted on it. The numbers start at 0, so the first locker is locker 0 and the second is locker 1. The last locker's number is always one less than the number of lockers.

In real life: Locker 0, locker 1, locker 2
In JavaScript: Indexes 0, 1, 2
In real life: The thing inside a locker
In JavaScript: The element stored at that index
In real life: How many lockers there are
In JavaScript: length: the last index plus one
In real life: Taking lockers away from the end
In JavaScript: Setting a smaller length removes elements from the end

This lesson uses ideas from earlier lessons:

  • Data types: there, typeof [] gave "object".
  • Objects & references: two names can point at the same object.
  • Object basics: how named properties work.
  • Loops and for…of & for…in: there you learned not to use for…in to read array values.
  • Manuals & specifications: it used .at() as an example entry. Now you will use it for real.

Two ways to make an array

STEP THROUGH

The usual way to make an array is an array literal: square brackets with the values inside, like ["Ada", "Grace"]. It is clear and safe.

There is also a function called Array(). You call it with the word new, like new Array(3). A function you call with new to make an object is called a constructor. It has one well-known trap: new Array(3) does not store the number 3. It makes an array whose length is 3, with nothing inside.

Square brackets or new Array()Pop out in the code editor (opens in a new tab)JavaScript
const cart = ["tea"];
const emptySlots = new Array(2);
console.log(cart.length);
console.log(emptySlots.length, 0 in emptySlots);

Line 1 makes an array with one real element, tea. Line 2 makes an array with two empty positions. Line 3 prints 1. Line 4 prints 2 false: the length is 2, but nothing is stored at index 0.

The in operator on line 4 asks a yes-or-no question. 0 in emptySlots means "is something stored at index 0 of emptySlots?" Here the answer is false. When you already know the values, use square brackets.

Left: the box cart, made with ["tea"], holds one card, tea. Its length is 1. Right: the box emptySlots, made with new Array(2), holds no cards at all, but its length says 2.["tea"]"tea"cartlength 1new Array(2)emptySlotslength 2, empty
Square brackets put real values in the array. new Array(2) puts nothing in. It only sets length to 2, so both positions are empty.
What does each line make?
Step 0 of 10Ready
Your turn: follow the blue line

Guess what each line makes before you step. The tricky one is new Array(3): it is not the same as [3].

Running in
  1. script
Next: line 1
const threeHoles = new Array(3);const twoValues = new Array(1, 2);const oneFromOf = Array.of(3);const withHole = [1, , 3];console.log(oneValue.length, 0 in oneValue);console.log(threeHoles.length, 0 in threeHoles);console.log(twoValues.join("-"));console.log(oneFromOf[0]);console.log(1 in withHole);
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

Commas need care too. A comma after the last value, as in [1, 2,], is allowed and adds nothing. Two commas in a row, as in [1, , 3], skip a position. Index 1 is then a hole: a position with nothing stored in it.

Two more ways to make arrays, Array.of() and Array.from(), come back in the next lesson, Slicing, splicing & joining. For now, square brackets are the best choice.

Real values or holes?
  • [3]
  • new Array(3)
  • new Array(1, 2)
  • Array.of(3)
  • [1, , 3]
  • [1, undefined, 3]
Try it yourself
0 of 6 correct

Sort each line of code into one of two groups: it makes real values, or it leaves holes. Each card explains why.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Reading by position, and what length means

INTERACTIVE

An index is a position number. Square brackets after the array's name read a position counted from the start: arr[0] is the first element.

The at() method reads a position too. arr.at(0) is also the first element. But at() also takes negative numbers, which count from the end. So arr.at(-1) is the last element.

If you ask for a position that does not exist, you get undefined. There is no error.

Read by position, then make the array shorter
Step 0 of 7Ready
Your turn: follow the blue line

Change the index, guess each read, then step through. Watch length = 2 make the real array shorter.

Running in
  1. script
Next: line 1
console.log(languages.at(0));console.log(languages.at(-1));console.log(languages[languages.length - 1]);console.log(languages[10]);console.log(languages.at(-10));languages.length = 2;console.log(languages);
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.
Read the first, the last, and a missing positionPop out in the code editor (opens in a new tab)JavaScript
const scores = [8, 13, 21];
console.log(scores[0]);
console.log(scores.at(-1));
console.log(scores.at(10));

Line 2 reads index 0, the first score: 8. Line 3 uses at(-1) to read the last score: 21. Line 4 asks for index 10. The array has only three elements, so it prints undefined.

length is a property, not a method, so you write it without round brackets: arr.length. Most of the time it is the number of elements in the list. The exact rule is: length is one more than the highest index.

You can also set length yourself:

  • Set it smaller, and the elements past the new end are removed.
  • Set it larger, and the new positions are holes.
A good habit

When you mean "the last element", write arr.at(-1). It says what you mean, and you don't have to write arr[arr.length - 1]. When you already have a position that is 0 or more, square brackets are fine.

Adding and removing at the ends

LIVE LAB

You can change an array after you make it. The first four methods to learn all work at one end of the list:

  • push(value) adds a value at the back. It returns the new length.
  • pop() removes the last value. It returns the value it removed.
  • unshift(value) adds a value at the front. It returns the new length.
  • shift() removes the first value. It returns the value it removed.
A row of three cards: Asha, Ben, Chen. On the left, at the front, unshift adds a card and shift removes one. On the right, at the back, push adds a card and pop removes one.unshift() addsshift() removes"Asha""Ben""Chen"push() addspop() removes
unshift() and shift() work at the front, where index 0 is. push() and pop() work at the back, after the last value.
Real-life analogyA stack of plates, and a line of people

Think of a stack of plates. You put a new plate on top, and you take the top plate off. Nothing else moves. That is like the back of an array.

Now think of people waiting in a line. When someone joins or leaves at the front, everyone behind them moves one place. Their place numbers all change. That is like the front of an array.

In real life: Put a plate on top
In JavaScript: push(value) adds at the back
In real life: Take the top plate off
In JavaScript: pop() removes from the back
In real life: Someone joins the front of the line
In JavaScript: unshift(value) adds at the front
In real life: The first person leaves the line
In JavaScript: shift() removes from the front
Live array lab
The code each button runsPop out in the code editor (opens in a new tab)JavaScript
const items = ["Ada", "Grace", "Linus"];items.push(value);items.pop();items.unshift(value);items.shift();items[5] = value;items.length = 2;
The array nowlength 3
index 0"Ada"
index 1"Grace"
index 2"Linus"
returned
—
last line run
const items = ["Ada", "Grace", "Linus"];
Try it yourself

The array starts with three names. Pick a button. Guess what it returns, then watch the boxes change.

Every button changes the same real array. Reset makes a new array with the three starting names.
Add a name, then remove onePop out in the code editor (opens in a new tab)JavaScript
const queue = ["Asha", "Ben"];
console.log(queue.push("Chen"));
console.log(queue.pop());
console.log(queue);

Line 2 runs push, which adds Chen at the back. It prints what push returns: the new length, 3. Line 3 runs pop, which removes the last value and returns it, so it prints Chen. Line 4 prints what is left: ["Asha", "Ben"].

The lab has two more buttons:

  • items[5] = value writes far past the end. The length jumps to 6, and the positions in between become holes.
  • items.length = 2 makes the array shorter. Every element after index 1 is removed.

Arrays are objects

STEP THROUGH

An array is a special kind of object. That means:

  • Two names can point at the same array, just like with any object.
  • You can add ordinary named properties to an array.
  • Its index numbers are really property names, stored as strings like "0".
  • typeof [] gives "object", not "array".

To check whether a value is an array, use Array.isArray(value). It returns true for an array and false for anything else.

Arrays are special objects
Step 0 of 7Ready
Your turn: follow the blue line

An array works like an object, with extra rules for elements and length.

Running in
  1. script
Next: line 1
tools.label = "toolbox";console.log(typeof tools);console.log(Array.isArray(tools));console.log(tools.length);console.log(tools[0] === tools["0"]);console.log(JSON.stringify(Object.keys(tools)));
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.
An array with an extra labelPop out in the code editor (opens in a new tab)JavaScript
const profile = ["Asha"];
profile.label = "team";
console.log(Array.isArray(profile));
console.log(profile.length);
console.log(profile.label);

Line 2 adds an ordinary property, label. Line 3 prints true, because profile is an array. Line 4 prints 1: the label is not an element, so the length does not change. Line 5 reads the label like any property and prints team.

The table compares the two kinds of data an array can hold. Read each row as a question.

Elements compared with named properties
QuestionAn elementA named property
What does it look like?arr[0] = "Ada"arr.label = "team"
Does it change length?Yes, when it is at or past the current end.No.
Do array methods use it?Yes. Methods like map and pop work with elements.Usually not.
What is its key?A string that looks like a number, such as "0".Any property name, such as "label".

This is why for…in is the wrong loop for reading array values. It walks through property names, so it can also pick up extra properties like label. Use for…of to read the values. Later lessons teach array methods for this too: Searching arrays, map, filter & reduce, and Sorting & copying safely.

Holes and sparse arrays

STEP THROUGH

A hole is a position with nothing stored in it. An array with holes is called a sparse array. A hole is different from a position that stores the value undefined. When you read either one, you get undefined.

The in operator shows the difference. 1 in arr is true only when something is really stored at index 1.

Left: the array [1, , 3] has nothing at index 1, so 1 in holey is false. Right: the array [1, undefined, 3] has a card that says undefined at index 1, so 1 in explicit is true.[1, , 3]1empty3index 11 in holey: false[1, undefined, 3]1undefined3index 11 in explicit: true
On the left, index 1 is a hole: nothing is stored there. On the right, index 1 holds the value undefined. Reading either one gives undefined, but only the in check tells them apart.
A hole has nothing stored in it
Step 0 of 10Ready
Your turn: follow the blue line

Step slowly. A hole has nothing stored in it; it is not a hidden undefined. Most code should not make holes.

Running in
  1. script
Next: line 1
const explicit = [1, undefined, 3];console.log(1 in holey);console.log(1 in explicit);const grown = ["a", "b"];grown[5] = "x";console.log(grown.length, 2 in grown, 5 in grown);console.log(holey.map((value) => value * 2));for (const value of holey) console.log(value);console.log(Array.from({ length: 3 }));
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.
const todo = ["read", , "ship"];
console.log(1 in todo);
console.log(todo[1]);

Line 1 skips index 1, so it is a hole. Line 2 prints false, because nothing is stored at index 1. Line 3 reads index 1 and still prints undefined. So reading a position cannot tell you whether something is stored there.

The table compares a hole with a stored undefined. Read across each row.

A hole compared with a stored undefined
QuestionHole: [1, , 3]Stored: [1, undefined, 3]
Is something stored at index 1?No. 1 in array is false.Yes. 1 in array is true.
What does reading index 1 give?It gives undefined.It gives undefined.
Do forEach and map visit index 1?No. They skip holes.Yes. They visit it like any element.
Should you make it on purpose?Almost never.Sometimes, when undefined has a meaning in your code.

The simple advice: don't make holes in everyday code. If you need empty places, put real values there, such as null, undefined, or an object that says what is missing. A later lesson, Fast arrays & elements kinds, shows how holes can also make code slower.

Where you’ll use this

Use an array whenever your data has an order. Two examples:

  • A web page keeps a list of notifications. When a new one arrives, it adds it with push. To show the newest one, it reads notifications.at(-1).
  • A text editor keeps a list of undo steps. It adds each action with push, and undoes the newest action with pop.
Add an item to a cartPop out in the code editor (opens in a new tab)JavaScript
const cart = ["tea"];
cart.push("bread");
console.log(cart.at(-1));
console.log(cart.length);

The cart starts with one item. Line 2 uses push to add bread. Line 3 reads the last item with at(-1) and prints bread. Line 4 prints the length, 2. A shopping site does the same thing when you add an item to your cart.

Here are more places where arrays fit well:

  • Queues: a list where the first one in is the first one out. Examples: people waiting for help, messages waiting to send.
  • Stacks: a list where the last one in is the first one out. Examples: undo history, the pages behind the Back button, dialogs opened on top of each other.
  • Rows of data: products, table rows, search results, points on a chart.
  • Changing every value: later lessons teach map, filter, and reduce.
Array or object?

Use an array when the order matters, or when the same value can appear twice. Use an object when you look things up by name. The later lesson Choosing a data structure helps you decide step by step.

Common misconceptions

“new Array(3) is the same as [3].”

No. new Array(3) makes an array with length 3 and three holes. To store the number 3, write [3] or Array.of(3).

“length counts the values.”

Not exactly. length is one more than the highest index. Holes still count toward it, even though nothing is stored there.

“push returns the item I pushed.”

No. push and unshift return the new length. pop and shift return the value they removed.

“A hole is just undefined.”

Reading a hole gives undefined, but nothing is stored at that index. The in operator tells the two apart.

“Arrays are not objects.”

They are a special kind of object. That is why named properties work on them, and why two names can point at one array.

Empty positions or stored undefined?Pop out in the code editor (opens in a new tab)JavaScript
const emptySlots = new Array(2);
const realUndefined = [undefined, undefined];
console.log(0 in emptySlots);
console.log(0 in realUndefined);

Reading index 0 gives undefined for both arrays. But line 3 prints false, because emptySlots has nothing stored at index 0. Line 4 prints true, because realUndefined stores undefined there. Use in when "nothing stored" and "stored undefined" must mean different things.

Practice: array basics

5 EXERCISES
Exercise 1 · Warm-upPredict the length

Predict the number that length prints after the three changes.

Starter codePop out in the code editor (opens in a new tab)JavaScript
const queue = ["Ada", "Grace"];
queue.push("Linus");
queue.unshift("Edsger");
queue.pop();
console.log(queue.length);

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · PracticeBuild a tiny undo stack

    An undo stack keeps actions in a list. Undo removes the newest one. The code uses push and pop to do this. What two lines print?

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    const undoStack = [];
    undoStack.push("typed heading");
    undoStack.push("added image");
    const lastAction = undoStack.pop();
    console.log(lastAction);
    console.log(undoStack.length);

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeRead the last item

      The code reads the last score with at(-1). What prints?

      Starter codePop out in the code editor (opens in a new tab)JavaScript
      const scores = [8, 13, 21];
      console.log(scores.at(-1));

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeFix the new Array(3) mistake

        A badge list should hold three real placeholder strings, not holes. The fixed code uses Array.from(). It makes an array of the given length and fills each position with what the arrow function returns. After the fix, what does line 3 print?

        Starter codePop out in the code editor (opens in a new tab)JavaScript
        const badges = Array.from({ length: 3 }, () => "new");
        console.log(badges.length);
        console.log(0 in badges);

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengeFind the hole

          The code uses the in operator to check whether something is stored at index 1. What prints?

          Starter codePop out in the code editor (opens in a new tab)JavaScript
          const items = ["first", , "third"];
          console.log(1 in items);

          Answer, then press Check. Spacing and letter case don’t matter.

            Quiz: check your understanding

            7 QUESTIONS

            Answer each question from memory first. Then read the explanation for every choice.

            Lesson quiz · 7 questionsScore: first tries count
            1. Question 1 of 7Which line of code makes an array that holds one value, the number 3?

              Choose an answer to see the explanation.

            2. Question 2 of 7What does at(-1) print here?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              const letters = ["a", "b", "c"];
              console.log(letters.at(-1));

              Choose an answer to see the explanation.

            3. Question 3 of 7What do push and length print here?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              const list = ["x", "y"];
              console.log(list.push("z"));
              console.log(list.length);

              Choose an answer to see the explanation.

            4. Question 4 of 7Which method removes the first element of an array and returns it?

              Choose an answer to see the explanation.

            5. Question 5 of 7What length prints after adding arr.label?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              const arr = ["a", "b"];
              arr.label = "letters";
              console.log(arr.length);

              Choose an answer to see the explanation.

            6. Question 6 of 7What do the two in checks print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              const holey = [1, , 3];
              const explicit = [1, undefined, 3];
              console.log(1 in holey);
              console.log(1 in explicit);

              Choose an answer to see the explanation.

            7. Question 7 of 7Why are shift and unshift usually slower than push and pop on very large arrays?

              Choose an answer to see the explanation.

            Key takeaways

            • Arrays keep values in order, at indexes that start at 0.
            • Make arrays with square brackets. new Array(3) makes three holes; [3] stores one value.
            • at(-1) reads the last element. Setting a smaller length removes elements from the end.
            • push and pop work at the back. unshift and shift work at the front, where every other element has to move.
            • Arrays are objects. A hole is a position with nothing stored in it. Avoid holes unless you have a clear reason.

            Remember the one-liner.
            An array is a special object that keeps a list of values in order, starting at index 0. Keep every position filled, and length tells you where the list ends.

            Up next: Slicing, splicing & joining.

            CompleteFrontend Clear concepts. Working examples.