Можно ли использовать цикл for...of для перебора ключей объекта в JavaScript?
Что проверяют
Понимаете ли вы разницу между итерируемым и перечисляемым, а не заучили ли список циклов. За ответом обычно идёт уточнение: чем for...in отличается от for...of, почему по Map цикл идёт, а по обычному объекту нет, и как добраться до ключей-символов.
Как отвечать
Начните с прямого «нет»: for...of работает с итерируемыми, то есть с объектами, у которых есть метод Symbol.iterator. У обычного объекта его нет, поэтому for (const key of obj) падает с TypeError: obj is not iterable. Дальше разложите варианты:
Object.keys(obj): массив собственных перечисляемых строковых ключей, по немуfor...ofуже идёт. РядомObject.valuesиObject.entriesс деструктуризацией:for (const [key, value] of Object.entries(obj));for...in: единственный цикл, который сам обходит ключи объекта, но поднимается по цепочке прототипов, поэтому чужие перечисляемые свойства попадут в перебор. Фильтр этоObject.hasOwn(obj, key)из ES2022, а неobj.hasOwnProperty(key);- символы и скрытые свойства:
Object.keysих не видит. Символы даётObject.getOwnPropertySymbols, неперечисляемыеObject.getOwnPropertyNames, всё сразуReflect.ownKeys; - порядок ключей: сначала целочисленные по возрастанию, потом строковые в порядке добавления, потом символы. Если порядок важен или ключи не строки, берите
Map: он итерируемый, иfor...ofпо нему выдаёт пары[key, value].
Хороший финал: объект можно сделать итерируемым руками, задав ему [Symbol.iterator], и тогда for...of заработает. Это показывает, что вы понимаете механику, а не помните запрет.
Где спотыкаются
Отвечают «нет» и замолкают. Интервьюер ждёт причину, а не факт, и без слов про протокол итерации ответ читается как заученный.
Зовут obj.hasOwnProperty(key) напрямую. На объекте из Object.create(null) этого метода нет, а в данных из внешнего источника поле hasOwnProperty может быть перезаписано кем угодно. Безопасный вариант это Object.hasOwn.
Тащат for...in на массивы. По массиву он выдаёт строковые индексы "0", "1" и прихватывает дописанные свойства, поэтому для массивов остаются for...of, forEach и обычный for по индексу.