Цепочки методов массивов в JavaScript
- Что такое цепочка методов
- Простой пример
- Когда использовать цепочку
- Когда лучше разбить на переменные
- Порядок методов
- Какие методы можно ставить в цепочку
- Итого
Цепочка методов массивов - это запись, где результат одного метода сразу передается следующему методу.
let numbers = [1, 2, 3, 4, 5, 6];
let result = numbers
.filter((number) => number % 2 === 0)
.map((number) => number * 10);
console.log(result); // [20, 40, 60]
Сначала filter() оставляет только четные числа. Потом map() умножает каждое из них на десять.
Что такое цепочка методов
Некоторые методы массивов возвращают новый массив. Например, filter() и map(). Поэтому после них можно сразу вызвать еще один метод массива.
let numbers = [1, 2, 3, 4];
let result = numbers.filter((number) => number > 2).map((number) => number * 2);
Такая запись корректна, но длинную цепочку обычно удобнее переносить на несколько строк.
let result = numbers
.filter((number) => number > 2)
.map((number) => number * 2);
Так легче увидеть каждый шаг.
Простой пример
Допустим, есть список товаров. Нужно взять только товары в наличии и получить их названия.
let products = [
{ title: 'Книга', price: 500, inStock: true },
{ title: 'Курс', price: 3000, inStock: false },
{ title: 'Подписка', price: 900, inStock: true },
];
let titles = products
.filter((product) => product.inStock)
.map((product) => product.title);
console.log(titles); // ['Книга', 'Подписка']
Здесь цепочка читается почти как инструкция: сначала отфильтровать, потом преобразовать.
Когда использовать цепочку
Цепочка хорошо подходит, когда несколько действий идут одно за другим и каждое действие достаточно простое.
let users = [
{ name: 'Анна', age: 22, active: true },
{ name: 'Олег', age: 17, active: true },
{ name: 'Мария', age: 30, active: false },
];
let names = users
.filter((user) => user.active)
.filter((user) => user.age >= 18)
.map((user) => user.name);
console.log(names); // ['Анна']
Такая цепочка уместна, потому что каждый шаг решает одну понятную задачу.
Обычно цепочка читается нормально, если в ней два-три простых шага. Если шагов становится больше, код может начать выглядеть тяжелым.
Когда лучше разбить на переменные
Если цепочка становится длинной или в callback-функциях появляется много условий, ее лучше разбить на несколько переменных.
let activeUsers = users.filter((user) => user.active);
let adultUsers = activeUsers.filter((user) => user.age >= 18);
let names = adultUsers.map((user) => user.name);
Кода стало больше, зато каждый промежуточный результат получил название. Это помогает читать и отлаживать программу.
Разбивать цепочку полезно, когда нужно посмотреть результат после отдельного шага через console.log().
console.log(activeUsers);
console.log(adultUsers);
Порядок методов
В цепочке важен порядок. Каждый следующий метод работает уже не с исходным массивом, а с результатом предыдущего шага.
let users = [
{ name: 'Анна', active: true },
{ name: 'Олег', active: false },
];
let names = users
.filter((user) => user.active)
.map((user) => user.name);
console.log(names); // ['Анна']
Если сначала сделать map(), то дальше в массиве будут уже строки, а не объекты.
let names = users
.map((user) => user.name)
.filter((name) => name.length > 3);
Это тоже может быть правильным кодом, но задача уже другая: фильтруются не пользователи, а имена.
Какие методы можно ставить в цепочку
В середине цепочки обычно используют методы, которые возвращают массив: map(), filter(), slice(), concat().
Методы, которые возвращают не массив, чаще завершают цепочку.
let total = products
.filter((product) => product.inStock)
.reduce((sum, product) => sum + product.price, 0);
console.log(total); // 1400
Здесь filter() возвращает массив, поэтому после него можно вызвать reduce(). А reduce() возвращает число, поэтому цепочка на нем заканчивается.
forEach() в цепочках обычно не используют, потому что он возвращает undefined.
let result = products.forEach((product) => {
console.log(product.title);
});
console.log(result); // undefined
Итого
1. Цепочка методов позволяет передавать результат одного метода сразу в следующий.
2. Цепочки хорошо подходят для простых последовательных действий, например filter().map().
3. Если цепочка становится длинной, ее лучше разбить на переменные.
4. Порядок методов важен, потому что каждый следующий метод работает с результатом предыдущего.
5. Методы вроде reduce(), find() и some() чаще завершают цепочку, а forEach() для цепочек обычно не подходит.