Как реализовать рекурсивную чистую функцию для инверсии значений в объекте в JavaScript
Что проверяют
Три вещи сразу: понимаете ли вы, что такое чистая функция, умеете ли писать рекурсию с корректным базовым случаем и продумываете ли крайние случаи данных. Следом обычно спрашивают про массивы, повторяющиеся значения и циклические ссылки.
Как отвечать
Сначала уточните, что значит «инверсия»: поменять местами ключи и значения или инвертировать сами значения (true в false, число в противоположное). Каркас рекурсии одинаков, меняется только обработка листа.
Чистота означает две вещи: входной объект не мутируется, и результат зависит только от аргумента. Поэтому новые объекты собираются через Object.entries и Object.fromEntries или reduce, а не присваиванием в исходник.
Каркас для обмена ключей и значений:
- базовый случай: примитив или
nullвозвращается как есть; - массив: проверка
Array.isArray, обход черезmapс рекурсивным вызовом, порядок сохраняется; - вложенный объект: ключ остаётся, значение инвертируется рекурсивно, иначе ключом станет строка
"[object Object]"; - лист: пара
[String(value), key], потому что ключ объекта всегда строка или символ; - собственные поля:
Object.entriesберёт только собственные перечисляемые свойства. Сfor...inфильтруйте черезObject.hasOwn, а неobj.hasOwnProperty, который падает на объектах без прототипа.
Отдельно проговорите, что считать простым объектом. Date, Map, Set и экземпляры классов тоже дают typeof v === "object", их лучше оставить листом или обработать явно. Проверка прототипа через Object.getPrototypeOf(v) на Object.prototype или null отсекает такие случаи.
Где спотыкаются
Не думают о коллизиях. Если значения повторяются, при обмене поздний ключ молча затирает ранний. Нужно либо сказать об этом, либо собирать ключи в массив.
Не защищаются от циклических ссылок. Рекурсия уходит в переполнение стека. Решение через WeakMap уже обработанных объектов, передаваемый параметром, сохраняет чистоту снаружи.
Мутируют аргумент ради «оптимизации», например через delete старого ключа. Функция перестаёт быть чистой, хотя проходит простые тесты.