Как проитерироваться по объекту в JavaScript
Что проверяют
Понимаете ли вы разницу между способами обхода: какие ключи попадают в перебор, откуда берутся унаследованные свойства и в каком порядке идут ключи. Следом часто просят объяснить, почему for...of по обычному объекту падает.
Как отвечать
for...in: перебирает перечисляемые строковые ключи, включая унаследованные по цепочке прототипов. Поэтому внутри нужна проверкаObject.hasOwn(obj, key). Она надёжнее старогоobj.hasOwnProperty(key), который ломается на объектах изObject.create(null);Object.keys,Object.values,Object.entries: только собственные перечисляемые свойства со строковыми ключами, сразу массивом. Дальшеfor...of,map,filter. Самый частый вариант в коде:for (const [key, value] of Object.entries(obj));Object.fromEntries: обратная операция. СвязкаObject.fromEntries(Object.entries(obj).map(...))собирает новый объект без мутаций, стандартный приём для редьюсеров и нормализации данных;Reflect.ownKeys: все собственные ключи, включая неперечисляемые и символы.
Про порядок: сначала целочисленные ключи по возрастанию, затем строковые в порядке добавления, символы в самом конце. Если порядок или нестроковые ключи важны, берите Map: он итерируемый, хранит порядок вставки и принимает ключом что угодно.
В React объект обычно превращают в массив через Object.entries и рендерят, используя ключ объекта как key элемента. Для асинхронной обработки подходит for...of с await внутри, а forEach промисы не ждёт.
Где спотыкаются
Пишут for (const x of obj) и получают TypeError: obj is not iterable. У обычного объекта нет Symbol.iterator, итерируются массивы, строки, Map и Set.
Используют for...in для массивов. Индексы приходят строками, "0" вместо 0, а свойства, добавленные в прототип сторонней библиотекой, попадают в перебор.
Рассчитывают на порядок вставки для ключей вида "10" и "2". Движок отсортирует их как числа, и список с сервера, пришедший объектом с id в роли ключей, внезапно перемешается.