Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Когда применяется цикл for...of
for...of — это синтаксис цикла, который предназначен для итерирования по итерируемым объектам (iterable objects). Это один из самых удобных способов обхода данных в современном JavaScript. Ключевое отличие от других циклов — for...of работает только с объектами, которые реализуют протокол итератора.
Основной синтаксис
for (const element of iterable) {
console.log(element);
}
Когда применяется for...of
1. Обход массивов
const numbers = [10, 20, 30, 40];
for (const num of numbers) {
console.log(num);
}
// Вывод: 10, 20, 30, 40
// Сравнение с for и forEach
for (let i = 0; i < numbers.length; i++) {
console.log(numbers[i]);
}
numbers.forEach((num) => {
console.log(num);
});
for...of предпочтительнее forEach, если нужна возможность break и continue.
2. Обход строк
Строки в JavaScript тоже итерируемые:
const word = 'hello';
for (const char of word) {
console.log(char);
}
// Вывод: h, e, l, l, o
// Полезно для работы с Unicode символами (в отличие от for loop)
const emoji = 'Hello😀';
for (const char of emoji) {
console.log(char);
}
// Вывод корректно обрабатывает эмодзи
3. Обход Set и Map
Set:
const set = new Set([1, 2, 3, 3, 4]);
for (const value of set) {
console.log(value);
}
// Вывод: 1, 2, 3, 4
Map:
const map = new Map([
['name', 'John'],
['age', 30],
['city', 'New York']
]);
for (const [key, value] of map) {
console.log(`${key}: ${value}`);
}
// Вывод:
// name: John
// age: 30
// city: New York
// Можно итерировать только ключи или значения
for (const key of map.keys()) {
console.log(key);
}
for (const value of map.values()) {
console.log(value);
}
4. Обход результатов querySelectorAll
const elements = document.querySelectorAll('.item');
for (const element of elements) {
element.classList.add('active');
}
5. Обход NodeList
const nodes = document.childNodes;
for (const node of nodes) {
if (node.nodeType === Node.ELEMENT_NODE) {
console.log(node.tagName);
}
}
6. Итерирование по объектам с Symbol.iterator
Любой объект можно сделать итерируемым, реализовав Symbol.iterator:
const range = {
from: 1,
to: 5,
[Symbol.iterator]() {
return {
current: this.from,
last: this.to,
next() {
if (this.current <= this.last) {
return { done: false, value: this.current++ };
} else {
return { done: true };
}
}
};
}
};
for (const value of range) {
console.log(value);
}
// Вывод: 1, 2, 3, 4, 5
for...of vs for vs forEach vs map
const arr = [1, 2, 3];
// 1. Традиционный for — полный контроль, работает везде
for (let i = 0; i < arr.length; i++) {
if (i === 1) break; // Можно прерывать
console.log(arr[i]);
}
// 2. for...of — удобен, работает с итерируемыми, поддерживает break/continue
for (const value of arr) {
if (value === 2) continue; // Пропускаем 2
console.log(value);
}
// 3. forEach — функциональный подход, не работает break/continue
arr.forEach((value, index) => {
console.log(value);
});
// 4. map — для трансформации массива, возвращает новый
const doubled = arr.map(x => x * 2);
Почему for...of лучше forEach
// for...of позволяет break и continue
for (const item of items) {
if (item.skip) continue;
if (item.stop) break;
process(item);
}
// forEach не позволяет прерывать
items.forEach(item => {
if (item.skip) return; // Только пропуск элемента, не цикла
process(item);
});
Async iteration — for await...of
Для работы с асинхронными итераторами:
const asyncIterable = {
[Symbol.asyncIterator]() {
let count = 0;
return {
async next() {
count++;
await new Promise(resolve => setTimeout(resolve, 100));
if (count <= 3) {
return { value: count, done: false };
}
return { done: true };
}
};
}
};
for await (const value of asyncIterable) {
console.log(value);
}
// Вывод через 100ms каждый: 1, 2, 3
// Практический пример: получение данных из API с пагинацией
async function* fetchPages() {
let page = 1;
while (true) {
const response = await fetch(`/api/data?page=${page}`);
const data = await response.json();
yield data;
if (data.lastPage) break;
page++;
}
}
for await (const page of fetchPages()) {
console.log(page.items);
}
Что НЕ является итерируемым
const obj = { a: 1, b: 2, c: 3 };
for (const value of obj) { // ОШИБКА!
console.log(value);
}
// Правильно: для обычных объектов используй Object.entries, Object.keys, Object.values
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}
for (const key of Object.keys(obj)) {
console.log(key);
}
for (const value of Object.values(obj)) {
console.log(value);
}
Резюме
for...of применяется для:
- Обхода массивов (более современен, чем for)
- Итерирования по Set, Map, строкам
- Обхода NodeList и других итерируемых объектов
- Случаев, когда нужны break и continue (в отличие от forEach)
- Работы с асинхронными итераторами (for await...of)
Преимущества for...of:
- Читаемый и понятный синтаксис
- Поддержка break, continue, return
- Работает со всеми итерируемыми объектами
- Потенциально более оптимален, чем forEach
Не используй for...of для:
- Обычных объектов (используй Object.entries, for...in)
- Трансформации данных (используй map, filter, reduce)