Что такое Array.prototype.group и Object.groupBy в JavaScript?

JuniorObject.groupBy / Map.groupBy · Frontend·Обновлено 11 сентября 2026
Коротко
Array.prototype.group — это отменённое предложение по группировке элементов массива, которое переросло в два статических метода: Object.groupBy() и Map.groupBy(). Они принимают массив (или другой итерируемый объект) и функцию-колбэк, которая для каждого элемента возвращает ключ группы, и возвращают объект (или Map) с сгруппированными элементами.

Что это такое

Одно время в TC39 обсуждалось предложение добавить метод Array.prototype.group(), который бы группировал элементы массива по ключу, возвращаемому функцией-колбэком, прямо на прототипе массива — по аналогии с map, filter, reduce.

Однако выяснилось, что имя group конфликтует с уже существующим нестандартным свойством Array.prototype.group, добавленным движком MooTools и всё ещё встречающимся на старых сайтах. Из-за риска сломать существующие страницы TC39 отказался от расширения прототипа массива и переработал предложение в два статических метода: Object.groupBy() и Map.groupBy().

Object.groupBy()

Object.groupBy(items, callback) принимает итерируемый объект (массив, Set, генератор и т.д.) и функцию, вызываемую для каждого элемента. Функция возвращает строку или символ — ключ группы. Результат — обычный объект без прототипа (Object.create(null)), где ключи — это группы, а значения — массивы элементов, попавших в эту группу.

const products = [
  { name: 'Яблоко', type: 'fruit' },
  { name: 'Морковь', type: 'vegetable' },
  { name: 'Банан', type: 'fruit' },
];

const grouped = Object.groupBy(products, (item) => item.type);
// {
//   fruit: [{ name: 'Яблоко', ... }, { name: 'Банан', ... }],
//   vegetable: [{ name: 'Морковь', ... }]
// }

Объект создаётся без прототипа специально, чтобы ключи вроде constructor или toString не конфликтовали со встроенными свойствами объекта.

Map.groupBy()

Map.groupBy(items, callback) работает так же, но возвращает Map вместо обычного объекта. Это полезно, когда ключом группы должно быть не только строка/символ, а произвольное значение — число, объект, NaN и т.д., потому что ключи Map не приводятся к строке.

const inventory = [
  { name: 'asparagus', quantity: 5 },
  { name: 'bananas', quantity: 0 },
  { name: 'goat', quantity: 23 },
];

const result = Map.groupBy(inventory, ({ quantity }) => quantity > 0);
// Map(2) { true => [ {asparagus...}, {goat...} ], false => [ {bananas...} ] }

Чем отличаются от reduce-группировки

До появления этих методов группировку писали через reduce:

const grouped = products.reduce((acc, item) => {
  (acc[item.type] ??= []).push(item);
  return acc;
}, {});

Object.groupBy/Map.groupBy — это тот же паттерн, но встроенный в язык: короче, декларативнее и без риска случайно перезаписать прототипные свойства.

Поддержка

Оба метода — часть стандарта ECMAScript 2024 (ES2024) и поддерживаются в актуальных версиях Chrome, Firefox, Safari и Node.js (начиная с 21 версии). Для старых окружений нужен полифилл или fallback на reduce.

Итог

Array.prototype.group — это историческое название несостоявшегося метода, который в итоге стал парой статических методов Object.groupBy и Map.groupBy, добавленных в ES2024 для декларативной группировки элементов коллекции по ключу.

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

Кандидат знает, что финальное имя метода — не Array.prototype.group, а Object.groupBy/Map.groupBy

Объясняет, почему предложение изменили (конфликт с legacy-свойством MooTools на Array.prototype)

Понимает сигнатуру: коллбэк возвращает ключ группы для каждого элемента

Знает разницу между Object.groupBy (обычный объект без прототипа) и Map.groupBy (Map с произвольными ключами)

Может сравнить с классическим способом группировки через reduce

Пример: Object.groupBy — группировка по типу

const products = [
  { name: 'Яблоко', type: 'fruit' },
  { name: 'Морковь', type: 'vegetable' },
  { name: 'Банан', type: 'fruit' },
];

const grouped = Object.groupBy(products, (item) => item.type);

console.log(grouped.fruit);
// [{ name: 'Яблоко', type: 'fruit' }, { name: 'Банан', type: 'fruit' }]

Пример: Map.groupBy — группировка по булеву значению

const inventory = [
  { name: 'asparagus', quantity: 5 },
  { name: 'bananas', quantity: 0 },
  { name: 'goat', quantity: 23 },
];

const restock = Map.groupBy(inventory, ({ quantity }) => quantity === 0);

console.log(restock.get(true));
// [{ name: 'bananas', quantity: 0 }]

Пример: Аналог через reduce (до ES2024)

function groupBy(array, keyFn) {
  return array.reduce((acc, item) => {
    const key = keyFn(item);
    // создаём массив для новой группы, если её ещё нет
    (acc[key] ??= []).push(item);
    return acc;
  }, {});
}

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

Утверждают, что метод называется Array.prototype.group и вызывается на массиве как array.group(...)

Не знают о конфликте имён, из-за которого метод не попал в Array.prototype

Путают порядок аргументов callback или забывают, что он возвращает именно ключ группы, а не сам элемент

Не упоминают, что Object.groupBy возвращает объект без прототипа (Object.create(null))

Не могут объяснить, зачем нужен отдельный Map.groupBy, если уже есть Object.groupBy

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

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

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 ₽
Подробнее