Цикл for…in
В прошлом уроке for…of шёл по списку покупок и выдавал сами пункты: молоко, хлеб, яблоки. Иногда нужны не пункты, а их номера, например чтобы написать рядом «1.», «2.», «3.».
Представьте гардероб. Вы сдаёте куртку и получаете номерок с надписью «12». На номерке написано число, но складывать номерки никто не станет: это ярлык, а не количество.
У for…of есть похожий цикл for…in. Он перебирает не элементы массива, а их индексы. И приходят индексы как раз такими номерками: строками, а не числами.
Индексы вместо значений
Давайте пройдём циклом for…in по массиву из трёх букв и выведем каждый индекс вместе с его типом:
const letters = ["x", "y", "z"];
for (const i in letters) {
console.log(i, typeof i);
}
// 0 string
// 1 string
// 2 stringРазберём по шагам:
- На первой итерации
iполучает индекс первого элемента — строку"0". typeof iдаёт"string", и программа выводит0 string.- Дальше
iполучает"1"и"2", а тип остаётся тем же. - Индексы кончились, и цикл останавливается сам.
Сами буквы "x", "y" и "z" цикл не выдал ни разу. Кавычек в выводе тоже нет: console.log печатает строки без них, поэтому "0" выглядит как число.
Почему индексы — строки
В JavaScript индекс массива работает как имя ячейки, а имена ячеек всегда хранятся строками. for…in перебирает именно эти имена, поэтому выдаёт "0", "1" и "2".
Тип индекса важен при сравнении. Внутри цикла проверка i === 0 всегда ложна: строгое равенство не приводит типы, и строка "0" не равна числу 0. Сравнивайте со строкой, i === "0", или с числом из неё, Number(i) === 0.
Здесь гардеробная аналогия перестаёт работать. Номерок нельзя превратить в количество, а строку-индекс можно: Number(i) даёт из "2" число 2.
По строке
По строке for…in тоже перебирает индексы-строки, а не символы:
for (const i in "ok") {
console.log(i, typeof i);
}
// 0 string
// 1 stringУ строки "ok" два символа, поэтому цикл выдаёт два индекса: "0" и "1". Сами буквы o и k даёт for…of. У строки из пяти символов индексы шли бы от "0" до "4".
Какой цикл выбрать
Правило выбора короткое:
- нужны элементы массива или символы строки — берите
for…of; - нужны индексы —
for…inих даст, но строками.
Разницу этих двух циклов часто спрашивают на собеседовании. Короткий ответ: for…of даёт значения, а for…in — индексы в виде строк.
Частая ошибка
Индекс из for…in использовали как число:
const scores = [10, 20];
for (const i in scores) {
console.log(i + 1); // ✗
}Ошибки нет, но программа выводит 01 и 11, а не 1 и 2. Индекс i — строка "0", а + со строкой склеивает, а не складывает.
Если нужен номер, переведите индекс в число:
const scores = [10, 20];
for (const i in scores) {
console.log(Number(i) + 1);
}
// 1
// 2Если нужны элементы, пишите for…of.
Главное
for…inперебирает индексы массива или строки, а не значения.- Индексы приходят строками:
"0","1","2". +со строкой-индексом склеивает; число из индекса даётNumber(i).- За значениями идут к
for…of, за индексами — кfor…in.
Подпишись, чтобы пройти курс
Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.