Array.prototype.flat()
The default depth is 1, not infinite — the mistake almost everyone makes on first use. Pass Infinity when you genuinely want it flat all the way down.
Demo
The input is nested three levels deep. Each increment of depth peels off exactly one layer, so depth 1 — the DEFAULT — leaves [3, [4]] still nested inside. That is the surprise: calling flat() with no argument on deeply nested data looks like it did almost nothing. Depth 0 returns the array unchanged, and only depth 3 (or Infinity) flattens this particular input completely.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| depth | number | no (1) | How many levels to flatten. 0 returns a shallow copy unchanged. Infinity flattens completely however deep the nesting goes. |
Return value
Array — A NEW array with nested arrays spliced in up to the given depth. Empty slots (holes) are removed along the way.
Common patterns
const allValues = nested.flat(Infinity);
const words = lines.flatMap(l => l.split(" "));
const dense = sparse.flat();
Examples
Pitfalls
[1, [2, [3]]].flat()
[1, [2, [3]]].flat(Infinity)
[1, , 3].flat().length
[1, , 3].map(x => x)
lines.map(l => l.split(" ")).flat()
lines.flatMap(l => l.split(" "))
nested.flat()
[].concat(...nested)
When to use
- Flattening arrays of arrays into a single list
- Normalising deeply nested data with Infinity
- Removing holes from a sparse array
- You are mapping then flattening → flatMap
- The nesting is deeper than one level and you called flat() → pass a depth
- Runtimes older than ES2019 → [].concat(...arrays)
Notes
FAQ
Because the default depth is 1 — it removes exactly one level of nesting. Anything deeper stays as it is. Pass Infinity to flatten completely regardless of how deep the structure goes.
[1, [2, [3]]].flat() // [1, 2, [3]] [1, [2, [3]]].flat(Infinity) // [1, 2, 3]