Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

JavaScript (ES2026)  Module 6 – Arrays and array methods

Arrays: creating, reading and length

Create JavaScript arrays, read items by index and with at(), learn what length counts, tell holes from undefined and build grids without shared rows.

  • Beginner
  • 15 minutes
  • Examples run with Node.js 24.21.0 and quickjs 0.32.0
  • By MySmartCoPilot
Free lesson, Pro answers: 15 minutes
Free: the whole lesson. With a pass: the model answers to its 2 interview questions.

What you will learn

  • Create arrays and read items by index, including negative indexes with at()
  • Explain length, holes (sparse arrays) and array-likes
  • Represent grids such as seat maps with nested arrays

Before you start

What you’ll learn · Before you start

What you will learn

  • Create arrays and read items by index, including negative indexes with at()
  • Explain length, holes (sparse arrays) and array-likes
  • Represent grids such as seat maps with nested arrays

Before you start

On this page

An array is JavaScript’s ordered list of values: the runs off each ball of an over, the seats in a row of a bus, the names in a queue. You create one with square brackets, const over = [1, 0, 4, 6, 0, 2], and read an item by its index, its position counted from 0, so over[0] is the first item and over[5] the sixth. over.at(-1) counts from the end and reads the last item. The length property is one more than the highest index, 6 here, and it changes when the array does. Reading a position where nothing is stored gives undefined, never an error. This lesson runs each of these rules, then looks at what length really counts, at the empty slots called holes, at array-likes that only look like arrays, and at grids made of arrays inside an array, including a bug that books a whole column of seats at once.

Create an array and read its items

Reading the six balls of an over JavaScript · first-array.mjs
// The runs scored off each ball of one over of cricket, in the order the six balls were bowled.
const over = [1, 0, 4, 6, 0, 2];

console.log('balls:', over.length);
console.log('first ball:', over[0], '| fourth ball:', over[3]);
console.log('seventh ball:', over[6]);
console.log('last ball:', over.at(-1), '| with length:', over[over.length - 1]);
console.log('over[-1]:', over[-1]);

// The scorer corrects the second ball: it went for 2 runs, not 0.
over[1] = 2;
console.log('after the correction:', over);

let total = 0;
for (const runs of over) total += runs;
console.log('runs in the over:', total);

Output

balls: 6
first ball: 1 | fourth ball: 6
seventh ball: undefined
last ball: 2 | with length: 2
over[-1]: undefined
after the correction: [ 1, 2, 4, 6, 0, 2 ]
runs in the over: 15

Recorded with Node.js 24.21.0 on macOS 26 arm64. To run it yourself: mise exec node@24.21.0 -- node first-array.mjs

The square brackets hold the items, separated by commas, and the array keeps them in the order you wrote them. The first item is at index 0 and the last at index length - 1, 5 for this over, so over[3] is the fourth ball, the six. Index 6 is past the end: nothing is stored there, and the read gives undefined without complaint, which is why a typo in an index often shows up much later as an undefined somewhere else.

To read from the end, at() takes a negative index: at(-1) is the last item and at(-2) the one before it. at() arrived in ECMAScript 2022 (Node.js 16.6, Chrome 92, Firefox 90 and Safari 15.4 have it); before that, the same read was written over[over.length - 1], which you will still meet in older code. Square brackets never count from the end: over[-1] looks for a property named "-1", which an array does not have, so it gives undefined.

Diagram: the six runs of an over at indexes 0 to 5, which at(-6) to at(-1) also reach; reads past either end give undefined.over (length 6)over[6], over[-1] and over.at(-7)are all undefined: no item is there1 [0]at(-6)0 [1]at(-5)4 [2]at(-4)6 [3]at(-3)0 [4]at(-2)2 [5]at(-1)past either end

Indexes from the front, and negative positions with at()

Text description of the diagram

The diagram shows the array over, which holds the runs 1, 0, 4, 6, 0 and 2 and has a length of 6.

  • Each box is one item, in two rows of three, read left to right. Under each value are two ways to reach it: the index in square brackets, counted from 0 at the front, and the negative position that at() accepts, counted from -1 at the end.
  • The first item, 1, is over[0] and over.at(-6). The last item, 2, is over[5] and over.at(-1).

A note under the row says that over[6], over[-1] and over.at(-7) all give undefined, because no item is there. Square brackets never count from the end: over[-1] looks for a property named "-1", which an array does not have.

An index can also stand on the left of =: over[1] = 2 replaces the second item in place, and the array stays the same array. for…of, from the control-flow module, then walks through the values in index order, which is how the program adds up the 15 runs of the over.

What length counts

length is not a count of the items you stored. The specification defines it as a number that is always greater than every index in the array, and the engine keeps that true whenever the array changes:

length follows the highest index, and writing it changes the array JavaScript · length-rules.mjs
// length is always one more than the highest index, and writing to length changes the array.
const queue = ['Asha', 'Ravi', 'Meena'];
console.log(typeof queue, Array.isArray(queue), Object.keys(queue));

queue[5] = 'Kiran';
console.log('after queue[5] = ...:', queue.length, queue);

queue.length = 2;
console.log('after length = 2:', queue, queue[2]);

const sameQueue = queue;
queue.length = 0;
console.log('after length = 0:', queue, sameQueue);

const tagged = ['a', 'b'];
tagged.label = 'not an index';
console.log('a non-index key leaves length at', tagged.length);

try {
  queue.length = -1;
} catch (error) {
  console.log('length = -1 throws', error.name);
}

Output

object true [ '0', '1', '2' ]
after queue[5] = ...: 6 [ 'Asha', 'Ravi', 'Meena', <2 empty items>, 'Kiran' ]
after length = 2: [ 'Asha', 'Ravi' ] undefined
after length = 0: [] []
a non-index key leaves length at 2
length = -1 throws RangeError

Recorded with Node.js 24.21.0 on macOS 26 arm64. To run it yourself: mise exec node@24.21.0 -- node length-rules.mjs

  • typeof queue is "object": an array is an object whose property names are its indexes, which is why Object.keys() lists them as the strings '0', '1' and '2'. Array.isArray() is the reliable test for an array, because typeof cannot tell an array from any other object.
  • Writing to index 5 of a three-item array makes length 6. Nothing was stored at indexes 3 and 4, so they are empty slots, shown as <2 empty items>; the next section is about them.
  • Setting length to a smaller number deletes every item from that index on: queue[2] is gone, not hidden.
  • queue.length = 0 empties the array in place. sameQueue names the same array, so it is empty too. Writing queue = [] instead would make a new, empty array for that one variable and leave every other reference holding the old items; with const, it is not even allowed.
  • A property whose name is not an index, such as tagged.label, does not change length. Arrays accept such properties because they are objects, but for…of, forEach() and the other array methods never see them, so keep extra data elsewhere.
  • length must be a whole number from 0 to 4,294,967,295 (2³² − 1). Setting it to a fraction or to a number outside that range, such as -1, throws a RangeError.

Holes: an empty slot is not undefined

An array whose length is larger than the number of items actually stored is sparse, and each missing item is a hole. A hole is not a slot holding undefined: nothing is stored there at all. The two look alike when you read them, and most of the time that is all that matters, but array methods treat them differently:

Three holes against three undefined values JavaScript · sparse-and-dense.mjs
// Holes against undefined values: Array(3) has three empty slots, Array.from({ length: 3 }) three undefined values.
const holes = Array(3);
const values = Array.from({ length: 3 });

console.log(holes, values);
console.log('is index 0 there?', 0 in holes, 0 in values);

let visits = 0;
holes.forEach(() => visits++);
console.log('forEach calls on holes:', visits);

console.log('map on holes:', holes.map(() => 'seat'));
console.log('map on values:', values.map(() => 'seat'));
console.log('spread of holes:', [...holes]);
console.log('JSON of [1, , 3]:', JSON.stringify([1, , 3]));

Output

[ <3 empty items> ] [ undefined, undefined, undefined ]
is index 0 there? false true
forEach calls on holes: 0
map on holes: [ <3 empty items> ]
map on values: [ 'seat', 'seat', 'seat' ]
spread of holes: [ undefined, undefined, undefined ]
JSON of [1, , 3]: [1,null,3]

Recorded with Node.js 24.21.0 on macOS 26 arm64. To run it yourself: mise exec node@24.21.0 -- node sparse-and-dense.mjs

Called with a single number, Array(3) (or new Array(3)) makes an array of length 3 with no items in it: three holes. Array.from({ length: 3 }) makes a dense array of the same length that stores undefined three times. The in operator tells them apart, since 0 in holes asks whether index 0 exists. From there the methods go their own ways:

  • forEach() skips holes, so it called its function 0 times; map() skips them too and keeps the holes in the new array it returns.
  • Spreading with [...holes] and looping with for…of read every index from 0 to length - 1, so a hole comes out as undefined.
  • JSON.stringify() writes null for a hole, because JSON has neither holes nor undefined.

Holes come from Array(n), from writing past the end, from delete list[i] and from a doubled comma in a literal, [1, , 3], which ESLint’s recommended rule no-sparse-arrays reports. Dense arrays are easier to reason about: create them with Array.from() or with fill(), and remove items with splice(), which the next lesson covers, rather than with delete. One more trap of the constructor: only a single number is taken as a length. Array(3, 4) is the two-item array [3, 4], and Array(2.5) throws a RangeError, because a length must be a whole number.

Array-likes look like arrays but are not

Some objects have a length and items at the indexes 0, 1, 2 and so on, without being arrays. They are called array-likes:

An object, a string and arguments, turned into arrays JavaScript · array-likes.mjs
// Array-likes have a length and index keys, but they are not arrays and have no array methods.
const picked = { 0: 'Mumbai', 1: 'Pune', 2: 'Nashik', length: 3 };
console.log(Array.isArray(picked), picked[1], picked.length, typeof picked.map);

const cities = Array.from(picked);
console.log(Array.isArray(cities), cities.at(-1), cities);

const word = 'chai';
console.log(word.length, word[0], word.at(-1), Array.from(word));

function scores() {
  return [arguments.length, Array.isArray(arguments), Array.from(arguments)];
}
console.log(scores(7, 9, 10));

Output

false Pune 3 undefined
true Nashik [ 'Mumbai', 'Pune', 'Nashik' ]
4 c i [ 'c', 'h', 'a', 'i' ]
[ 3, false, [ 7, 9, 10 ] ]

Recorded with Node.js 24.21.0 on macOS 26 arm64. To run it yourself: mise exec node@24.21.0 -- node array-likes.mjs

picked has index keys and a length, so picked[1] works, but it has none of the array methods: picked.map is undefined, and Array.isArray() says false. Strings are array-likes too, and so is the arguments object that every regular function receives. In a browser you will meet others: document.querySelectorAll() returns a NodeList, which the DOM module covers. Array.from() copies any array-like, or anything you can loop over with for…of, into a real array, which then has every method of this module. For a string it gives the characters one by one, keeping a character such as 😀 in one piece, the same way for…of does.

Grids: arrays inside an array

An item of an array can be another array, and that is how JavaScript holds a table, a game board or the seats of a bus. The outer array holds the rows, and each row holds its seats:

A bus seat map with four bookings JavaScript · seat-map.mjs
// A bus with 5 rows of 4 seats, A and B on the left of the aisle and C and D on the right.
// Each row is its own array, built by Array.from, so booking a seat changes one row only.
const ROWS = 5;
const LETTERS = 'ABCD';
const seats = Array.from({ length: ROWS }, () => Array(LETTERS.length).fill('open'));

function book(seat) {
  const row = Number(seat.slice(0, -1)) - 1; // '3C' → row index 2
  const column = LETTERS.indexOf(seat.at(-1)); // 'C' → column index 2
  seats[row][column] = 'booked';
}

for (const seat of ['1A', '1B', '3C', '5D']) book(seat);

const mark = (seat) => (seat === 'open' ? '.' : 'X');
console.log('    A B   C D');
for (let r = 0; r < seats.length; r++) {
  const [a, b, c, d] = seats[r];
  console.log(`${String(r + 1).padStart(2)}  ${mark(a)} ${mark(b)}   ${mark(c)} ${mark(d)}`);
}

let open = 0;
for (const row of seats) {
  for (const seat of row) if (seat === 'open') open++;
}
console.log(`${open} of ${ROWS * LETTERS.length} seats are open; seat 3C is ${seats[2][2]}`);

Output

    A B   C D
 1  X X   . .
 2  . .   . .
 3  . .   X .
 4  . .   . .
 5  . .   . X
16 of 20 seats are open; seat 3C is booked

Recorded with Node.js 24.21.0 on macOS 26 arm64. To run it yourself: mise exec node@24.21.0 -- node seat-map.mjs

seats[2][2] reads in two steps: seats[2] is the third row, and [2] picks its third seat, 3C. The program builds the grid with Array.from({ length: ROWS }, () => …), which calls the arrow function once for every row and stores what it returns, so each row is a new array of four 'open' seats. The function also receives the index of the slot it fills, as its second argument: Array.from({ length: 3 }, (_, i) => i * i) gives [0, 1, 4]. Reading a row that does not exist gives undefined, and reading a seat of undefined throws a TypeError, so check the row first or read it with optional chaining, seats[9]?.[0].

The shared-row bug

The shorter way to build a grid looks right and is wrong:

fill() with an array: one row in every slot JavaScript · shared-row-bug.mjs
// fill() puts the value it is given in every slot. Given an array, it stores the SAME array three times.
const wrong = Array(3).fill(Array(3).fill('.'));
wrong[0][1] = 'X';
console.log(wrong);
console.log('wrong[0] === wrong[2]:', wrong[0] === wrong[2]);

// Array.from calls its function once per slot, and each call makes a new row.
const right = Array.from({ length: 3 }, () => Array(3).fill('.'));
right[0][1] = 'X';
console.log(right);
console.log('right[0] === right[2]:', right[0] === right[2]);

Output

[ [ '.', 'X', '.' ], [ '.', 'X', '.' ], [ '.', 'X', '.' ] ]
wrong[0] === wrong[2]: true
[ [ '.', 'X', '.' ], [ '.', '.', '.' ], [ '.', '.', '.' ] ]
right[0] === right[2]: false

Recorded with Node.js 24.21.0 on macOS 26 arm64. To run it yourself: mise exec node@24.21.0 -- node shared-row-bug.mjs

fill(value) stores the value it is given in every slot, and the argument Array(3).fill('.') is evaluated once, before fill() runs. So the outer array holds the same row three times. Writing an 'X' into wrong[0][1] changes that single row, and all three rows show it, because there is only one; wrong[0] === wrong[2] is true. With Array.from(), the arrow function runs three times and makes three rows, and the 'X' stays in row 0:

Diagram: fill() stores one row array in all three slots of a grid; Array.from builds a separate row for each slot.Array(3).fill(row)Array.from({ length: 3 },makeRow)wrong: slot 0 | slot 1 | slot 2ONE row: '.', 'X', '.'right: slot 0 | slot 1 | slot 2three rowsrow 0: '.', 'X', '.'row 1: '.', '.', '.'row 2: '.', '.', '.'all three slotspoint hereone rowper slotthe fix

One shared row, or one row per slot

Text description of the diagram

The diagram has two panels, one above the other.

  • The first panel is the grid made with Array(3).fill(Array(3).fill('.')). Its three slots all point to one and the same row array, so writing 'X' into wrong[0][1] puts the X in that single row, and all three rows of the grid show it.
  • The second panel is the grid made with Array.from({ length: 3 }, () => Array(3).fill('.')). Array.from calls the arrow function once for each slot, so there are three separate rows. Writing 'X' into right[0][1] changes row 0 only; rows 1 and 2 still hold three dots.

An arrow from the first panel to the second is labelled "the fix".

The same trap waits in Array(n).fill({}) and Array(n).fill([]), which share one object or one array among all the slots. Copying the grid does not separate the rows either: [...wrong] is a new outer array that holds the same shared row, three times. In a seat-booking screen this bug books seat B in every row at once, and the exercise below asks you to build grids that cannot have it.

JavaScript & TypeScript Online Compiler Paste shared-row-bug.mjs and change wrong[0][1] to wrong[2][0]: see which seats change in each grid. JSON Formatter Paste the JSON of a grid, such as [[1,2,3],[4,5,6]], to see its rows laid out one inside the other.

Exercises

Exercise · Easy · JavaScript

Build a grid without shared rows, then transpose it

Write two functions in grid.mjs. A grid is an array of rows, and each row is an array of the same length.

  • createGrid(rows, cols, value) returns a new grid with rows rows of cols items, every item set to value. createGrid(2, 3, 0) returns [[0, 0, 0], [0, 0, 0]], and createGrid(0, 4, '.') returns []. Every row must be a separate array: changing grid[0][0] must leave every other row as it was.
  • transpose(grid) returns a new grid whose rows are the columns of grid: transpose([[1, 2, 3], [4, 5, 6]]) returns [[1, 4], [2, 5], [3, 6]]. An empty grid gives [], and the grid passed in must not change.

The starter's createGrid() looks right but builds its grid with fill(), and transpose() has no body yet. Run the sample tests when you are done.

Starter code · grid.mjs

// The grid helpers of lesson javascript/arrays-basics. A grid is an array of rows of the same length.

export function createGrid(rows, cols, value) {
  // Looks right, but fill() puts the same row array in every slot.
  return Array(rows).fill(Array(cols).fill(value));
}

export function transpose(grid) {
  // Return a new grid whose rows are the columns of grid.
}
The sample tests · grid.test.mjs
import { test, assert } from 'mysmartcopilot:test';
import { createGrid, transpose } from './grid.mjs';

test('a 2 by 3 grid of zeros', () => {
  assert.deepEqual(createGrid(2, 3, 0), [[0, 0, 0], [0, 0, 0]]);
});

test('every row is a separate array', () => {
  const grid = createGrid(3, 2, '.');
  grid[0][0] = 'X';
  assert.deepEqual(grid, [['X', '.'], ['.', '.'], ['.', '.']]);
  assert.ok(grid[1] !== grid[2]);
});

test('a grid with no rows is an empty array', () => {
  assert.deepEqual(createGrid(0, 4, '.'), []);
});

test('transposing a 2 by 3 grid gives a 3 by 2 grid', () => {
  assert.deepEqual(transpose([[1, 2, 3], [4, 5, 6]]), [[1, 4], [2, 5], [3, 6]]);
});

test('one row becomes one column, and an empty grid stays empty', () => {
  assert.deepEqual(transpose([[7, 8, 9]]), [[7], [8], [9]]);
  assert.deepEqual(transpose([]), []);
});

test('transpose leaves its input as it was', () => {
  const input = [['a', 'b'], ['c', 'd']];
  const result = transpose(input);
  assert.deepEqual(result, [['a', 'c'], ['b', 'd']]);
  assert.deepEqual(input, [['a', 'b'], ['c', 'd']]);
  assert.ok(result !== input && result[0] !== input[0]);
});
A hint

Array(rows).fill(row) stores one row in every slot. Array.from({ length: rows }, () => …) calls its function once for every slot, so a function that returns a new row gives each slot a row of its own. In transpose(), the result has one row for each column of grid, and row c of the result holds item c of every row of grid. Mind the empty grid: it has no first row to measure.

The sample tests run on this device, in your browser (QuickJS): nothing is sent to mysmartcopilot.com. The first run downloads JavaScript (about 0.6 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.

Check yourself

6 questions about this lesson. Every answer and why it is right is on the page, behind “Show the answer”. Your score stays in this browser.

  1. Question 1 of 6 What does this program print?

    Read the code, then choose one answer.

    const marks = [72, 35, 91];
    
    console.log(marks[3], marks.at(-1), marks[-1]);
    Show the answer to question 1

    Answer: undefined 91 undefined

    Index 3 is past the last item, which is at index 2, so marks[3] is undefined; reading outside an array never throws. at(-1) counts from the end and gives 91. Square brackets do not count from the end: marks[-1] looks for a property named "-1", which does not exist.

  2. Question 2 of 6 const list = ['a', 'b', 'c', 'd']; list.length = 1; What does list hold now?

    Choose one answer.

    Show the answer to question 2

    Answer: ['a']

    Setting length to a smaller number deletes every item whose index is not below the new length, so only index 0 survives. Setting it to 0 empties the array, for every variable that refers to it.

  3. Question 3 of 6 const slots = []; slots[4] = 'E'; What is slots.length?

    Type a number.

    Show the answer to question 3

    Answer: 5

    length is always one more than the highest index. Writing to index 4 makes the length 5, and indexes 0 to 3 are holes: empty slots with no value stored.

  4. Question 4 of 6 What does this program print?

    Read the code, then choose one answer.

    const grid = Array(2).fill([]);
    grid[0].push('x');
    
    console.log(grid);
    Show the answer to question 4

    Answer: [ [ 'x' ], [ 'x' ] ]

    fill([]) evaluates [] once and stores that one array in both slots, so pushing into grid[0] changes the only row there is. Array.from({ length: 2 }, () => []) makes a new array for each slot.

  5. Question 5 of 6 Which of these create an array of length 3 whose items forEach() calls its function for? Choose every right one.

    Choose every answer that is right.

    Show the answer to question 5

    Answer:

    • Array.from({ length: 3 })
    • [undefined, undefined, undefined]

    Array(3) and new Array(3) make a sparse array: length 3 but no items at all, three holes that forEach() skips. Array.from({ length: 3 }) and the literal store three real undefined values, which forEach() visits.

  6. Question 6 of 6 What does sparse-and-dense.mjs print?

    What does this program print? Choose one answer.

    // Holes against undefined values: Array(3) has three empty slots, Array.from({ length: 3 }) three undefined values.
    const holes = Array(3);
    const values = Array.from({ length: 3 });
    
    console.log(holes, values);
    console.log('is index 0 there?', 0 in holes, 0 in values);
    
    let visits = 0;
    holes.forEach(() => visits++);
    console.log('forEach calls on holes:', visits);
    
    console.log('map on holes:', holes.map(() => 'seat'));
    console.log('map on values:', values.map(() => 'seat'));
    console.log('spread of holes:', [...holes]);
    console.log('JSON of [1, , 3]:', JSON.stringify([1, , 3]));
    Show the answer to question 6

    Answer: it prints

    [ <3 empty items> ] [ undefined, undefined, undefined ]
    is index 0 there? false true
    forEach calls on holes: 0
    map on holes: [ <3 empty items> ]
    map on values: [ 'seat', 'seat', 'seat' ]
    spread of holes: [ undefined, undefined, undefined ]
    JSON of [1, , 3]: [1,null,3]

    Array(3) stores no items, so in finds no index 0, forEach() calls nothing and map() keeps the holes. Spreading reads every index from 0 to length - 1 and gets undefined for each hole, and JSON has no holes, so JSON.stringify() writes null in their place.

Interview questions

Fresher · What is the difference between a hole and undefined in a JavaScript array?

A hole is an index where nothing is stored at all, while undefined is a value stored at an index like any other. Array(3) has three holes, and Array.from({ length: 3 }) stores undefined three times; both have length 3 and both give undefined when you read an item, so a plain read cannot tell them apart. The in operator can: 0 in Array(3) is false. Methods differ too: forEach(), map() and filter() skip holes, while for…of, spreading and Array.from() turn them into undefined, and JSON.stringify() writes null. Holes come from Array(n), from writing past the end, from delete and from a doubled comma in a literal. Avoid them by creating arrays with Array.from() or fill().

Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.

  1. Fresher to mid

    A bus-booking page builds its seat map with Array(rows).fill(Array(4).fill('open')). After one customer books seat 3B, every row shows seat B as booked. Explain the cause, how you would prove it in a debugger or a test, and two correct ways to build the map.

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Fresher to mid

    A class register stores marks with marks[rollNumber] = score, and the roll numbers are 101, 205 and 340. The report prints "Class size: 341", the average is wrong, and JSON.stringify(marks) is mostly null. Explain what happened to the array, and what you would store instead.

    Model answer, Pro. First step and follow-ups

Key takeaways

  • [a, b, c] creates an array; list[i] reads the item at index i, counted from 0, and list.at(-1) reads the last item. A read where nothing is stored gives undefined.
  • length is one more than the highest index. Writing past the end grows it and leaves holes; setting it smaller deletes items, and list.length = 0 empties the array for every reference to it.
  • Array.isArray() tells an array from other objects; typeof gives "object" for both.
  • Array(3) makes three holes, which forEach() and map() skip; Array.from({ length: 3 }) makes three real undefined values.
  • Array-likes such as strings, arguments and a NodeList have a length and index keys but no array methods; Array.from() turns them into arrays.
  • Build grids with Array.from({ length: rows }, () => Array(cols).fill(value)). Array(rows).fill(row) stores one row in every slot, and a change to one seat shows in every row.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.