Что такое Array.flat и flatMap в JavaScript?

JuniorJavaScript · Frontend·Обновлено 2 августа 2026
Коротко
Array.flat(depth) создаёт новый массив, разворачивая вложенные подмассивы на указанную глубину. Array.flatMap(fn) применяет функцию к каждому элементу и разворачивает результат на один уровень — это эффективная замена map().flat(1).

Array.flat

Метод Array.flat() создаёт новый массив, объединяя все вложенные подмассивы в один. Принимает необязательный параметр depth, определяющий глубину разворачивания (по умолчанию 1).

Основные особенности

  • Создаёт новый массив, не мутирует исходный.
  • Пустые ячейки (holes) в разреженных массивах удаляются.
  • Передача Infinity разворачивает массив любой глубины вложенности.
const arr = [1, [2, [3, [4]]]];

arr.flat();          // [1, 2, [3, [4]]] — глубина 1 по умолчанию
arr.flat(2);         // [1, 2, 3, [4]]
arr.flat(Infinity);  // [1, 2, 3, 4]

// Разреженные массивы — дыры удаляются
[1, , 2, , 3].flat(); // [1, 2, 3]

Array.flatMap

Метод Array.flatMap() сначала применяет функцию-маппер к каждому элементу, а затем разворачивает результат ровно на один уровень. Семантически эквивалентен arr.map(...).flat(1), но работает за один проход — это делает его более эффективным по памяти и производительности.

const sentences = ['Hello world', 'foo bar'];

// Без flatMap — два прохода
sentences.map(s => s.split(' ')).flat();
// ['Hello', 'world', 'foo', 'bar']

// С flatMap — один проход, результат идентичен
sentences.flatMap(s => s.split(' '));
// ['Hello', 'world', 'foo', 'bar']

Фильтрация через flatMap

Один из паттернов — возвращать пустой массив для элементов, которые нужно пропустить. Это совмещает маппинг и фильтрацию в одной операции.

const numbers = [1, 2, 3, 4, 5];

// Удваиваем чётные числа, нечётные пропускаем
const result = numbers.flatMap(n => n % 2 === 0 ? [n, n * 2] : []);
// [2, 4, 4, 8]

flat vs flatMap — ключевые отличия

flat flatMap
Аргумент глубина (число) функция-маппер
Глубина разворачивания любая всегда 1
Назначение только разворачивание трансформация + разворачивание

Поддержка и полифил

Оба метода появились в ES2019 (ES10) и поддерживаются во всех современных браузерах. Для устаревших окружений используют полифил через reduce:

// Полифил flat(1)
const flatten = arr => arr.reduce((acc, val) => acc.concat(val), []);

// Полифил flatMap
const flatMap = (arr, fn) => arr.reduce((acc, val, i) => acc.concat(fn(val, i, arr)), []);

Что хочет услышать интервьюер

Понимание разницы между flat и flatMap: flat только разворачивает, flatMap сначала преобразует, потом разворачивает

Знание параметра depth у flat и того, что flatMap всегда разворачивает только на 1 уровень

Понимание, что оба метода не мутируют исходный массив и возвращают новый

Осознание практической пользы flatMap — один проход вместо map().flat(1), паттерн фильтрации через пустой массив

Знание версии ES, в которой появились методы (ES2019), и наличие полифилов

Пример: flat — разворачивание вложенных массивов

const nested: number[][][] = [[[1, 2]], [[3, 4]], [[5]]];

// Глубина 1 — разворачивает один уровень
nested.flat();
// [[1, 2], [3, 4], [5]]

// Глубина 2 — разворачивает до плоского массива
nested.flat(2);
// [1, 2, 3, 4, 5]

// Произвольная вложенность
const deep = [1, [2, [3, [4, [5]]]]];
deep.flat(Infinity);
// [1, 2, 3, 4, 5]

Пример: flatMap — трансформация и разворачивание

// Разбиваем предложения на слова
const phrases: string[] = ['apple orange', 'foo bar baz'];
const words = phrases.flatMap(phrase => phrase.split(' '));
// ['apple', 'orange', 'foo', 'bar', 'baz']

// Паттерн: map + filter за один проход
const orders: Array<{ id: number; items: string[] }> = [
  { id: 1, items: ['book', 'pen'] },
  { id: 2, items: [] },           // пустой заказ
  { id: 3, items: ['notebook'] },
];

// Получаем все товары, игнорируя пустые заказы
const allItems = orders.flatMap(order =>
  order.items.length > 0 ? order.items : []
);
// ['book', 'pen', 'notebook']

Типичные ошибки

Считают, что flatMap разворачивает на произвольную глубину — он всегда разворачивает только на 1 уровень

Забывают передать depth в flat при глубокой вложенности и удивляются неполному результату

Путают порядок операций в flatMap: сначала map, потом flat — а не наоборот

Не знают о паттерне фильтрации через пустой массив [] в flatMap

Не помнят, что flat удаляет дыры в разреженных массивах (sparse arrays)

Лучшие курсы по теме

изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Feature-Sliced Design

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.6
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее