Массивы: перебор
for
Классический:
const items = ['a', 'b', 'c'];
for (let i = 0; i < items.length; i++) {
console.log(i, items[i]);
}
Можно break и continue.
for...of
Современный:
for (const item of items) {
console.log(item);
}
С индексом:
for (const [index, item] of items.entries()) {
console.log(index, item);
}
Можно break, continue, await.
for...in
Не используй для массивов. Итерирует по ключам, включая неиндексные свойства:
const arr = [1, 2, 3];
arr.custom = 'x';
for (const key in arr) {
console.log(key); // '0', '1', '2', 'custom'
}
forEach
items.forEach((item, index, array) => {
console.log(item, index);
});
Нельзя прервать. Возвращает undefined.
map
Преобразует каждый элемент, возвращает новый массив:
const doubled = [1, 2, 3].map((x) => x * 2); // [2, 4, 6]
С индексом:
['a', 'b'].map((item, i) => `${i}: ${item}`); // ['0: a', '1: b']
filter
Оставляет подходящие:
const evens = [1, 2, 3, 4].filter((x) => x % 2 === 0); // [2, 4]
reduce
Сворачивает в одно значение:
const sum = [1, 2, 3].reduce((acc, x) => acc + x, 0); // 6
С объектом:
const grouped = ['a', 'b', 'a'].reduce((acc, x) => {
acc[x] = (acc[x] ?? 0) + 1;
return acc;
}, {});
// { a: 2, b: 1 }
Без начального значения — первое значение берётся как стартовое:
[1, 2, 3].reduce((acc, x) => acc + x); // 6
Без начального значения на пустом массиве — ошибка:
[].reduce((a, b) => a + b); // TypeError
Всегда указывай начальное значение.
some и every
[1, 2, 3].some((x) => x > 2); // true
[1, 2, 3].every((x) => x > 0); // true
some — хотя бы один. every — все.
find и findIndex
[1, 2, 3].find((x) => x > 1); // 2
[1, 2, 3].findIndex((x) => x > 1); // 1
[1, 2, 3].findLast((x) => x > 1); // 3
Цепочки
const result = users
.filter((u) => u.active)
.map((u) => u.name)
.sort();
Каждый метод возвращает новый массив. Оригинал не меняется.
Прерывание цепочек
forEach, map, filter нельзя прервать. Для прерывания — for...of или some/every:
[1, 2, 3, 4].some((x) => {
if (x > 2) return true; // прервёт
console.log(x);
return false;
});
Итераторы
const iterator = arr[Symbol.iterator]();
iterator.next(); // { value: 1, done: false }
Используется редко напрямую.
entries, keys, values
const arr = ['a', 'b'];
[...arr.entries()]; // [[0, 'a'], [1, 'b']]
[...arr.keys()]; // [0, 1]
[...arr.values()]; // ['a', 'b']
Производительность
forиfor...ofбыстрееforEachmap,filterсоздают новые массивы- Цепочки
map+filterпроходят массив несколько раз reduce— один проход
Для больших данных — for или reduce.
Итоги
for,for...of,forEach— переборmap,filter,reduce— преобразованиеsome,every,find— проверкиforEachне прерывается- Цепочки создают новые массивы
for...of— универсальный