# An introduction to JavaScript Arrays

> Learn JavaScript array basics: create arrays, access values, understand length and empty slots, add or remove items, combine arrays, and find values.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2017-08-24 | Updated: 2026-07-18 | Topics: [JavaScript](https://flaviocopes.com/tags/js/) | Canonical: https://flaviocopes.com/javascript-array/

An array stores an ordered collection of values.

JavaScript arrays are resizable objects. They can contain values of different types:

```js
const values = [1, 'Flavio', true, { color: 'blue' }]
```

Use `Array.isArray()` when you need to check a value:

```js
Array.isArray(values) //true
typeof values //'object'
```

The [MDN Array reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) and the [ECMAScript Array specification](https://tc39.es/ecma262/2026/multipage/indexed-collections.html#sec-array-objects) document every method and edge case.

## Create an array

The simplest way to create an array is an array literal:

```js
const empty = []
const numbers = [1, 2, 3]
```

`Array.of()` creates an array from its arguments:

```js
const numbers = Array.of(1, 2, 3)
```

Be careful with the `Array` constructor. One numeric argument creates an array with that length, not an array containing the number:

```js
const slots = Array(3)
const number = Array.of(3)

slots.length //3
number //[3]
```

The three positions in `slots` are empty slots. They do not contain `undefined` values.

Use `fill()` when you want actual values in every position:

```js
const zeros = Array(3).fill(0)

zeros //[0, 0, 0]
```

`Array.from()` creates an array from an iterable or array-like value:

```js
const letters = Array.from('hello')

letters //['h', 'e', 'l', 'l', 'o']
```

## Access array items

Array indexes start at zero:

```js
const fruits = ['banana', 'pear', 'apple']

fruits[0] //'banana'
fruits[1] //'pear'
fruits[2] //'apple'
fruits[3] //undefined
```

Use `at()` when a negative index is useful:

```js
fruits.at(-1) //'apple'
```

You can assign through an index too:

```js
fruits[1] = 'mango'

fruits //['banana', 'mango', 'apple']
```

## Nested arrays

JavaScript does not have a separate multidimensional array type. You create one by nesting arrays:

```js
const matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]

matrix[0][0] //1
matrix[2][0] //7
```

## Understand `length`

The `length` property is always greater than every array index. In a dense array, it is one greater than the last index.

It is not always the number of populated elements in a sparse array.

```js
const numbers = [1, 2, 3]

numbers.length //3
```

Reducing `length` deletes values beyond the new length:

```js
const numbers = [1, 2, 3]

numbers.length = 2
numbers //[1, 2]
```

Increasing it creates empty slots:

```js
const numbers = [1, 2]

numbers.length = 4
numbers //[1, 2, <2 empty items>]
```

Empty slots behave differently from explicit `undefined` values in some array methods. Avoid creating sparse arrays unless you specifically need them.

See the [MDN `length` reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length) for the exact rules.

## Add items

`push()` adds one or more values to the end and returns the new length:

```js
const numbers = [1, 2]

numbers.push(3, 4) //4
numbers //[1, 2, 3, 4]
```

`unshift()` does the same at the beginning:

```js
const numbers = [1, 2]

numbers.unshift(-1, 0) //4
numbers //[-1, 0, 1, 2]
```

Both methods change the original array.

## Remove items

`pop()` removes and returns the last value:

```js
const numbers = [1, 2, 3]
const last = numbers.pop()

last //3
numbers //[1, 2]
```

`shift()` removes and returns the first value:

```js
const numbers = [1, 2, 3]
const first = numbers.shift()

first //1
numbers //[2, 3]
```

Both return `undefined` when the array is empty.

## Combine arrays

`concat()` returns a new shallow array:

```js
const first = [1, 2]
const second = [3, 4]
const numbers = first.concat(second)

numbers //[1, 2, 3, 4]
```

Spread syntax is another common option:

```js
const first = [1, 2]
const second = [3, 4]
const numbers = [...first, ...second]
```

Neither example changes `first` or `second`. Nested objects are still shared because these copies are shallow.

## Find an item

`find()` returns the first value that passes a test:

```js
const posts = [
  { id: 1, title: 'Learning JavaScript' },
  { id: 2, title: 'Learning CSS' }
]

const post = posts.find(post => post.id === 2)

post.title //'Learning CSS'
```

It returns `undefined` when no value matches.

`findIndex()` returns the first matching index, or `-1`:

```js
const numbers = [10, 20, 30]

numbers.findIndex(number => number > 15) //1
```

`findLast()` and `findLastIndex()` search from the end.

Use `includes()` when you only need to check whether a value is present:

```js
const colors = ['blue', 'green', 'red']

colors.includes('green') //true
colors.includes('blue', 1) //false
```

The second argument is the index where the search starts, and that index is included.

## Mutating and copying methods

Some methods change the original array. Examples include `push()`, `pop()`, `shift()`, `unshift()`, `sort()`, `reverse()`, and `splice()`.

Others return a new array. Examples include `concat()`, `slice()`, `map()`, and `filter()`.

Modern JavaScript also provides copying versions of common mutating operations:

- `toSorted()`
- `toReversed()`
- `toSpliced()`
- `with()`

Use them when you need the result without changing the original array.
