Цикл for...in
Цикл for...in
Технический фундамент for...in
for...in - это цикл по перечислимым именам свойств объекта.
Он возвращает ключи (включая потенциально унаследованные), а доступ к значениям выполняется отдельно через индексную нотацию.
Ключевой момент: for...in проходит по именам свойств, а не по значениям и не по итератору.
Проверь себя: почему for...in и for...of нельзя считать взаимозаменяемыми?
Базовый синтаксис
const user = {
name: 'Anna',
role: 'student',
isActive: true,
};
for (const key in user) {
console.log(key, user[key]);
}
Смотри, что важно: значение берется через user[key], потому что key - динамическая строка.
for...in и объекты
Это основной сценарий for...in.
const settings = { theme: 'dark', lang: 'ru' };
for (const key in settings) {
console.log(`${key}: ${settings[key]}`);
}
Цикл полезен, когда заранее неизвестно, какие именно поля пришли.
Почему не стоит использовать for...in для массива
for...in по массиву вернет индексы как строки, и поведение может быть неочевидным.
const arr = [10, 20, 30];
for (const key in arr) {
console.log(key); // '0', '1', '2'
}
Для массивов обычно лучше for...of или классический for.
Здесь часто путаются: for...in технически "работает" для массива, но не лучший выбор по смыслу.
Проверь себя: какой цикл ты выберешь, если нужен именно элемент массива, а не его индекс?
Защита от унаследованных свойств
for...in может пройти по унаследованным перечислимым свойствам. В прикладном коде чаще фильтруют только собственные.
const base = { inherited: 1 };
const obj = Object.create(base);
obj.own = 2;
for (const key in obj) {
console.log(key); // 'own', 'inherited'
}
for (const key in obj) {
if (Object.hasOwn(obj, key)) {
console.log(key, obj[key]);
}
}
Смотри, что важно: это особенно актуально в универсальных утилитах, где объект приходит извне.
Мини-сценарий: валидация полей формы
const form = { email: 'a@mail.com', age: 20, agreed: true };
for (const key in form) {
if (form[key] === null || form[key] === undefined) {
console.log('missing:', key);
}
}
for...in здесь удобен, потому что проверка одинаковая для всех ключей объекта.
Дополнительный пример для новичка: собрать только заполненные поля
const profile = { name: 'Ann', city: '', age: 20 };
const filled = {};
for (const key in profile) {
if (!Object.hasOwn(profile, key)) continue;
if (profile[key] === '') continue;
filled[key] = profile[key];
}
console.log(filled); // { name: 'Ann', age: 20 }
Здесь видно сразу две базовые техники: фильтрация собственных свойств и работа с динамическим ключом через obj[key].
Частые ошибки новичков
- Применять
for...inк массивам без причины. - Путать ключ и значение в теле цикла.
- Забывать про фильтр собственных свойств.
- Использовать точечную нотацию
obj.keyвместоobj[key]внутри цикла.
Анти-провал: если цель - значения массива, бери for...of; если цель - ключи объекта, бери for...in.
Что будет, если изменить входные данные
Если в объекте появятся новые поля, for...in автоматически начнет их обрабатывать - это плюс для универсальных проверок. Но если объект содержит неожиданные унаследованные свойства, без hasOwn ты можешь обработать лишнее.
Проверь себя: в каких сценариях фильтр Object.hasOwn обязателен?
Краткий итог
for...inпредназначен для перебора ключей объекта.- Внутри цикла значение берут через
obj[key]. - Для массивов этот цикл обычно не лучший выбор.
- В надежном коде полезно фильтровать только собственные свойства.
- Правильный выбор цикла по типу данных делает логику чище и безопаснее.