---
title: "JavaScript Array Methods Cheatsheet"
slug: "javascript-array-methods"
category: "cheatsheets"
tags: ["cheatsheets", "javascript", "arrays", "functional", "reference", "frontend"]
status: "stable"
last_updated: 2026-05-14
summary: "JavaScript array method quick-reference with return types, mutation status, and the behavior details that matter for correctness."
related:
  [
    "[[coding/typescript]]",
    "[[cheatsheets/typescript-utility-types]]",
    "[[frontend/react-hooks]]",
    "[[coding/typescript-narrowing]]",
    "[[comparisons/typescript-vs-javascript]]",
    "[[frontend/react]]",
    "[[cheatsheets/index|Cheatsheets]]",
  ]
---

## Overview

JavaScript arrays carry two families of methods: those that return a new array or value (functional, non-mutating) and those that modify the array in place (mutating). Mixing the two families without awareness causes bugs in React state and other frameworks where mutation bypasses change detection. This card groups methods by behavior. All examples are vanilla JavaScript; TypeScript types are inferred correctly for all of these.

## Transform methods (return new array)

None of these modify the original array.

| Method       | Signature                             | Returns                | Notes                                                                 |
| ------------ | ------------------------------------- | ---------------------- | --------------------------------------------------------------------- |
| `map`        | `arr.map(fn)`                         | New array, same length | Transform every element.                                              |
| `filter`     | `arr.filter(fn)`                      | New array, subset      | Keep elements where `fn` returns truthy.                              |
| `flatMap`    | `arr.flatMap(fn)`                     | New array              | `map` then one level of `flat`. Replaces `arr.map(...).flat()`.       |
| `flat`       | `arr.flat(depth)`                     | New array              | Flatten nested arrays. Default depth is 1; `Infinity` fully flattens. |
| `slice`      | `arr.slice(start, end)`               | New array              | Shallow copy of a range; negative indices count from end.             |
| `concat`     | `arr.concat(other)`                   | New array              | Join two or more arrays; does not mutate either side.                 |
| `toSorted`   | `arr.toSorted(fn)`                    | New array              | Non-mutating sort (ES2023).                                           |
| `toReversed` | `arr.toReversed()`                    | New array              | Non-mutating reverse (ES2023).                                        |
| `toSpliced`  | `arr.toSpliced(start, del, ...items)` | New array              | Non-mutating splice (ES2023).                                         |
| `with`       | `arr.with(index, value)`              | New array              | Non-mutating element replacement (ES2023).                            |

```js
const nums = [1, 2, 3, 4, 5]

nums.map((x) => x * 2) // [2, 4, 6, 8, 10]
nums.filter((x) => x % 2 === 0) // [2, 4]
nums.flatMap((x) => [x, -x]) // [1, -1, 2, -2, 3, -3, 4, -4, 5, -5]
;[
  [1, 2],
  [3, [4]],
].flat() // [1, 2, 3, [4]]
;[
  [1, 2],
  [3, [4]],
].flat(Infinity) // [1, 2, 3, 4]
```

## Reduce and fold

Collapse an array to a single value.

| Method        | Signature                      | Returns   | Notes                                                                                        |
| ------------- | ------------------------------ | --------- | -------------------------------------------------------------------------------------------- |
| `reduce`      | `arr.reduce(fn, initial)`      | Any value | Left fold. Always pass an `initial` value; omitting it makes empty-array behavior undefined. |
| `reduceRight` | `arr.reduceRight(fn, initial)` | Any value | Right fold; rarely needed.                                                                   |

```js
const sum = [1, 2, 3, 4].reduce((acc, x) => acc + x, 0) // 10

// Group by a key
const byStatus = items.reduce((acc, item) => {
  ;(acc[item.status] ??= []).push(item)
  return acc
}, {})
```

## Search methods

Find elements or their positions.

| Method              | Returns                               | Mutates | Notes                                                           |
| ------------------- | ------------------------------------- | ------- | --------------------------------------------------------------- |
| `find(fn)`          | First matching element or `undefined` | No      | Returns the element itself.                                     |
| `findIndex(fn)`     | Index or `-1`                         | No      | Index of the first match.                                       |
| `findLast(fn)`      | Last matching element or `undefined`  | No      | ES2023; search from end.                                        |
| `findLastIndex(fn)` | Index or `-1`                         | No      | ES2023.                                                         |
| `indexOf(val)`      | Index or `-1`                         | No      | Strict equality; no function; use for primitives.               |
| `includes(val)`     | Boolean                               | No      | Returns true/false; handles `NaN` correctly (unlike `indexOf`). |
| `some(fn)`          | Boolean                               | No      | True if any element matches. Short-circuits.                    |
| `every(fn)`         | Boolean                               | No      | True if all elements match. Short-circuits.                     |

```js
const users = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" },
]

users.find((u) => u.id === 2) // {id: 2, name: 'Bob'}
users.findIndex((u) => u.id === 2) // 1
users.some((u) => u.name === "Bob") // true
users.every((u) => u.id > 0) // true
;[NaN].includes(NaN) // true
;[NaN].indexOf(NaN) // -1 (indexOf does not handle NaN)
```

## Iteration methods

Run a side effect per element.

| Method        | Returns                      | Mutates | Notes                                                        |
| ------------- | ---------------------------- | ------- | ------------------------------------------------------------ |
| `forEach(fn)` | `undefined`                  | No      | For side effects; cannot break early; cannot return a value. |
| `entries()`   | Iterator of `[index, value]` | No      | Use in `for...of` loops.                                     |
| `keys()`      | Iterator of indices          | No      |                                                              |
| `values()`    | Iterator of values           | No      |                                                              |

```js
arr.forEach((item, i) => console.log(i, item))

for (const [i, v] of arr.entries()) {
  console.log(i, v)
}
```

Prefer `for...of` over `forEach` when you need `break`, `continue`, or `await` inside the loop. `forEach` does not propagate promise rejections.

## Mutating methods

These change the array in place. Avoid with React state; create a copy first.

| Method                         | Returns              | What it does                                         |
| ------------------------------ | -------------------- | ---------------------------------------------------- |
| `push(...items)`               | New length           | Append to end.                                       |
| `pop()`                        | Removed element      | Remove from end.                                     |
| `unshift(...items)`            | New length           | Prepend to start.                                    |
| `shift()`                      | Removed element      | Remove from start.                                   |
| `splice(start, del, ...items)` | Removed elements     | Insert/delete/replace at index.                      |
| `sort(fn)`                     | Same array (mutated) | In-place sort; use `toSorted` for non-mutating.      |
| `reverse()`                    | Same array (mutated) | In-place reverse; use `toReversed` for non-mutating. |
| `fill(val, start, end)`        | Same array           | Fill a range with a value.                           |
| `copyWithin(target, start)`    | Same array           | Copy a slice to another position within the array.   |

```js
// Safe React state update: copy before mutating
setItems((prev) => [...prev, newItem]) // push equivalent
setItems((prev) => prev.filter((x) => x.id !== id)) // delete equivalent
```

## Access and structural methods

| Method                 | Returns                | Notes                                                                  |
| ---------------------- | ---------------------- | ---------------------------------------------------------------------- |
| `at(index)`            | Element or `undefined` | Supports negative indices: `arr.at(-1)` is last element.               |
| `length`               | Number                 | Property, not a method; settable to truncate.                          |
| `Array.from(iterable)` | New array              | Convert any iterable or array-like.                                    |
| `Array.isArray(val)`   | Boolean                | Reliable type check; `typeof` returns `"object"` for arrays.           |
| `Array.of(...items)`   | New array              | Avoids `Array(3)` ambiguity (creates hole-y array vs 3-element array). |
| `join(sep)`            | String                 | Concatenate elements with separator.                                   |

## Common gotchas

- `sort()` converts elements to strings by default. `[10, 2, 1].sort()` returns `[1, 10, 2]`. Always pass a comparator: `arr.sort((a, b) => a - b)`.
- `forEach` returns `undefined`. Assigning `const result = arr.forEach(...)` is always wrong.
- `map` on a sparse array preserves holes. `Array(3).fill(0).map(...)` works; `Array(3).map(...)` produces holes.
- `reduce` without an `initial` value throws on an empty array. Pass `0`, `[]`, or `{}` as the initial value.
- `at(-1)` is cleaner than `arr[arr.length - 1]`. Both return `undefined` for empty arrays.
- `splice` both mutates the array and returns the removed elements. The side-effect-plus-return pattern surprises people who expect it to work like `slice`.
- The `toSorted`, `toReversed`, `toSpliced`, and `with` methods require Node 20+ and are not available in older browsers without a polyfill.

## Related

- [[coding/typescript]]
- [[cheatsheets/typescript-utility-types]]
- [[frontend/react-hooks]]
- [[coding/typescript-narrowing]]
- [[comparisons/typescript-vs-javascript]]
- [[frontend/react]]
- [[cheatsheets/index|Cheatsheets]]
