← Назад к вопросам
При использовании for...in в массиве будут ключи или значения
2.0 Middle🔥 111 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
for...in в массиве: ключи или значения?
Ответ: for...in возвращает ключи (индексы), не значения.
Это один из самых частых источников ошибок у JavaScript разработчиков.
Демонстрация
const fruits = ['apple', 'banana', 'cherry'];
// for...in - возвращает ИНДЕКСЫ (ключи)
for (const index in fruits) {
console.log(index); // '0', '1', '2' (строки!)
console.log(fruits[index]); // 'apple', 'banana', 'cherry'
}
// Результат вывода:
// 0
// apple
// 1
// banana
// 2
// cherry
Почему индексы, а не значения?
for...in предназначена для итерации по объектам, а не массивам:
// Объект - for...in работает идеально
const user = {
name: 'John',
age: 30,
email: 'john@example.com'
};
for (const key in user) {
console.log(key); // 'name', 'age', 'email'
console.log(user[key]); // 'John', 30, 'john@example.com'
}
Массив - это тоже объект, с числовыми ключами:
const arr = ['a', 'b', 'c'];
// Внутренне это:
const arr = {
0: 'a',
1: 'b',
2: 'c',
length: 3
};
// for...in итерирует по ключам, как и для объекта
for (const key in arr) {
console.log(key); // '0', '1', '2'
}
Проблема: type вращается как строка
const numbers = [10, 20, 30];
for (const index in numbers) {
console.log(typeof index); // 'string'
console.log(index); // '0', '1', '2' (строки!)
console.log(index + 1); // '01', '11', '21' (конкатенация!)
}
// Результат:
// string
// 0
// 01 <- ОШИБКА! Ожидаем 1
// string
// 1
// 11 <- ОШИБКА! Ожидаем 2
// string
// 2
// 21 <- ОШИБКА! Ожидаем 3
Главная проблема: for...in итерирует по всем свойствам
const arr = ['a', 'b', 'c'];
// Добавляем свойство (не элемент массива)
arr.customProperty = 'hello';
for (const key in arr) {
console.log(key);
}
// Результат:
// '0'
// '1'
// '2'
// 'customProperty' <- ПРОБЛЕМА! Это не элемент массива
Правильные способы итерирации по массиву
1. for...of - для значений (рекомендуется)
const fruits = ['apple', 'banana', 'cherry'];
// for...of - возвращает ЗНАЧЕНИЯ
for (const fruit of fruits) {
console.log(fruit); // 'apple', 'banana', 'cherry'
}
2. forEach - с индексом если нужен
const fruits = ['apple', 'banana', 'cherry'];
fruits.forEach((fruit, index) => {
console.log(index, fruit); // 0 'apple', 1 'banana', 2 'cherry'
});
3. for loop - классический способ
const fruits = ['apple', 'banana', 'cherry'];
for (let i = 0; i < fruits.length; i++) {
console.log(i, fruits[i]); // 0 'apple', 1 'banana', 2 'cherry'
}
4. map - для преобразования
const numbers = [1, 2, 3];
const doubled = numbers.map((num, index) => {
console.log(index, num); // 0 1, 1 2, 2 3
return num * 2;
});
console.log(doubled); // [2, 4, 6]
Сравнение методов итерации
const arr = ['a', 'b', 'c'];
// 1. for...in - ключи объекта (НЕ для массивов!)
for (const key in arr) {
console.log(key); // '0', '1', '2'
console.log(typeof key); // 'string'
}
// 2. for...of - значения (рекомендуется)
for (const value of arr) {
console.log(value); // 'a', 'b', 'c'
}
// 3. forEach - значение + индекс
arr.forEach((value, index) => {
console.log(index, value); // 0 'a', 1 'b', 2 'c'
});
// 4. map - с преобразованием
const result = arr.map((value, index) => {
return `${index}: ${value}`;
});
console.log(result); // ['0: a', '1: b', '2: c']
// 5. entries - ключ и значение одновременно
for (const [index, value] of arr.entries()) {
console.log(index, value); // 0 'a', 1 'b', 2 'c'
}
Таблица сравнения
Метод | Возвращает | Для чего | Тип значения
──────────────┼─────────────────┼──────────────────────┼──────────────
for...in | ключи | объекты | строка
for...of | значения | массивы, итерируемые | любой
forEach | значение+индекс | массивы | любой
map | новый массив | преобразование | любой
entries | пара [индекс] | массивы с индексами | массив
while | (ручное) | любые | (ручное)
for (;;) | (ручное) | любые | (ручное)
Практические примеры ошибок
Ошибка 1: for...in вместо for...of
// НЕПРАВИЛЬНО
const items = ['item1', 'item2', 'item3'];
for (const item in items) {
console.log(item.toUpperCase()); // ERROR! item это '0', '1', '2' (строки)
}
// 0.toUpperCase() -> Error: 0 is not a function
// ПРАВИЛЬНО
for (const item of items) {
console.log(item.toUpperCase()); // 'ITEM1', 'ITEM2', 'ITEM3'
}
Ошибка 2: Арифметика с индексом
const numbers = [10, 20, 30];
// НЕПРАВИЛЬНО
for (const i in numbers) {
console.log(i + 5); // '05', '15', '25' (конкатенация!)
}
// ПРАВИЛЬНО
for (let i = 0; i < numbers.length; i++) {
console.log(i + 5); // 5, 6, 7
}
Ошибка 3: Проверка свойств
const arr = [1, 2, 3];
arr.custom = 'value';
// НЕПРАВИЛЬНО - итерирует и custom
for (const key in arr) {
console.log(arr[key]); // 1, 2, 3, 'value'
}
// ПРАВИЛЬНО
for (const value of arr) {
console.log(value); // 1, 2, 3 (custom не включается)
}
Когда использовать for...in
// for...in ХОРОШ для объектов:
const config = {
host: 'localhost',
port: 3000,
debug: true
};
for (const key in config) {
console.log(`${key}: ${config[key]}`);
}
// host: localhost
// port: 3000
// debug: true
// for...in НЕ РЕКОМЕНДУЕТСЯ для массивов:
// Используй for...of вместо
Финальная рекомендация
// НИКОГДА не используй for...in для массивов:
const arr = [1, 2, 3];
for (const index in arr) { // ❌ ПЛОХО
// ...
}
// ВСЕГДА используй for...of:
for (const value of arr) { // ✅ ХОРОШО
// ...
}
// Или если нужен индекс:
arr.forEach((value, index) => { // ✅ ХОРОШО
// ...
});
// Или entries для пар:
for (const [index, value] of arr.entries()) { // ✅ ХОРОШО
// ...
}
Заключение
for...in в массиве возвращает индексы (ключи) как строки, а не значения. Это источник многих ошибок. Используй:
- for...of для значений
- forEach если нужен индекс
- for...in только для объектов