Two-dimensional array
A two-dimensional array (or an array of arrays) is a data structure in which every element is itself an array. Put simply, it is a table: rows and columns, like in Excel or in a mathematical matrix. JavaScript has no separate "matrix" type; a two-dimensional array is an ordinary Array that holds other Array values.
Theory
TL;DR
- A two-dimensional array is a normal array whose elements are arrays.
- You reach an element through two indexes:
matrix[row][column]. - The first index is the row, the second is the column.
- To walk over every element you use nested loops.
- Build an empty matrix with
Array.from, becauseArray(n).fill(Array(m))gives you n references to one and the same row. - Rows may have different lengths: JavaScript does not require a rectangular shape.
Quick example
const matrix = [
[1, 2, 3], // row 0
[4, 5, 6], // row 1
[7, 8, 9] // row 2
];
console.log(matrix[0]); // [1, 2, 3] - the first row
console.log(matrix[1][2]); // 6 - second row, third columnHere matrix[0] returns the whole row [1, 2, 3], while matrix[1][2] returns one specific number from the second row and third column.
What it looks like as a table
The same array is easiest to picture as a grid:
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]| 0 | 1 | 2 | |
|---|---|---|---|
| 0 | 1 | 2 | 3 |
| 1 | 4 | 5 | 6 |
| 2 | 7 | 8 | 9 |
The row headers are the first index, the column headers are the second.
Accessing elements
console.log(matrix[0][0]); // 1
console.log(matrix[2][1]); // 8The first index is the row, the second is the column. Order matters: matrix[2][1] and matrix[1][2] are different cells. Reading a row that does not exist gives undefined, and immediately applying a second index to it (matrix[9][0]) throws a TypeError.
Iterating over all elements
The classic way is nested loops:
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
console.log(matrix[i][j]);
}
}iis the row number,jis the column number.
Note that the inner loop is bounded by matrix[i].length, not by some shared width. That is exactly what keeps the traversal correct for jagged arrays, where rows have different lengths.
The same thing with for...of reads more compactly:
for (const row of matrix) {
for (const value of row) {
console.log(value);
}
}Creating an empty matrix
const rows = 3;
const cols = 4;
const matrix = Array.from({ length: rows }, () => Array(cols).fill(0));
console.log(matrix);
/*
[
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
]
*/Array.from calls the factory function separately for each row, so every row is a brand new array.
Where it is used and a short recap
Two-dimensional arrays are commonly used for:
- storing tables and numeric matrices;
- representing game boards (chess, tic-tac-toe, for example);
- storing coordinate pairs (x, y);
- working with images, pixels, grids and so on.
| Term | Meaning |
|---|---|
| Two-dimensional array | An array where each element is an array |
| Indexing | [row][column] |
| Example | matrix[1][2] returns 6 |
| Typically used for | Tables, grids, coordinates, matrices |
Bottom line: a two-dimensional array is a "table in code": an array made of other arrays. It lets you store data conveniently as rows and columns.
Common mistakes
Array(3).fill(Array(3).fill(0)). All three "rows" are the same reference, somatrix[0][0] = 1changes the first column in every row. UseArray.from({ length: 3 }, () => Array(3).fill(0))instead.- Swapped indexes.
matrix[column][row]instead ofmatrix[row][column]gives you either the wrong value or an out-of-range read. - Hard-coded width. The condition
j < matrix[0].lengthbreaks on jagged rows; usematrix[i].length. - Treating
matrix.lengthas the cell count. It is the number of rows, not the total number of elements. - Copying with spread.
[...matrix]copies only the outer array; the nested rows stay shared. An independent copy needsmatrix.map(row => [...row]). - Reading from a row that does not exist.
matrix[99][0]throws aTypeErrorbecausematrix[99]isundefined; check bounds or usematrix[99]?.[0].
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.