Почему нельзя использовать Map вместо объекта для возвращаемого значения метода groupBy в JavaScript
Что проверяют
Понимаете ли вы, что выбор между объектом и Map это выбор контракта возвращаемого значения, а не спор о скорости. Вопрос с подвохом: в стандарте есть и Object.groupBy, и Map.groupBy, значит «нельзя» тут про конкретную ситуацию, а не про язык.
Как отвечать
Начните с того, что технически можно, и уточните контракт метода. Если результат уходит в JSON.stringify, в расширение через спред, в деструктуризацию или в пропсы компонента, Map ломает вызывающий код: сериализация даст пустой объект, спред тоже, а обращение по имени поля вернёт undefined вместо массива.
Дальше разница по существу:
- ключи объекта приводятся к строке, поэтому
1и"1"схлопнутся в одну группу.Mapсравнивает по SameValueZero, различает их и умеет объекты и символы в роли ключей; - порядок обхода объекта не совпадает с порядком вставки: целочисленные ключи идут первыми по возрастанию. Для группировки по годам или по идентификаторам это заметно.
Mapхранит порядок вставки; - у объекта есть прототип, и ручная группировка через
acc[key] ??= []спотыкается о ключи вродеconstructor. СпасаетObject.create(null), и ровно так устроен результатObject.groupBy.
const byRole = Object.groupBy(users, (u) => u.role); // ключи строковые
const byDept = Map.groupBy(users, (u) => u.dept); // ключом может быть объектВывод: объект удобнее как результат публичного API и для сериализации, Map честнее, когда ключ не строка или важен порядок.
Где спотыкаются
Спорят о производительности вслепую. На типичных размерах разница незаметна, измерений у кандидата нет, и аргумент рассыпается от первого уточняющего вопроса.
Второе: утверждают, что порядок ключей объекта не определён. Он определён и именно поэтому неудобен: числовые ключи всегда всплывают вверх независимо от порядка вставки.
Третье: возвращают Map, а тесты и логирование пишут через JSON.stringify. Метод работает верно, лог показывает пустые скобки, и полдня уходит на поиск несуществующей ошибки группировки.