Итак, 2020 не за горами и вы наверняка уже могли встретить мнение, что использовать циклы в Javascript становится немодным, deprecated, но почему? Давайте попробуем разобраться.

Одним из законодателей моды крупных разработчиков, имеющих свой style guide наравне с google сегодня является всем известный airbnb. Что же они думаю по этому поводу?

Итераторы и генераторы

11.1 Не используйте итераторы. Используйте JavaScript функции высшего порядка вместо циклов for-in or for-of. eslint: no-iterator no-restricted-syntax 
Почему? Это наше неизменное правило. Иметь дело с чистыми функциями возвращающими значение проще, чем бороться с сайд-эффектами. 
Используйте map() / every() / filter() / find() / findIndex() / reduce() / some() / ... для итерации массивов, 
и Object.keys() / Object.values() / Object.entries() для получения массивов, чтобы можно было итерировать объекты.

Давайте попробуем рассмотреть на практике, что же это значит и сравним императивный стиль (обычные javascript циклы) с декларативным (es6 синтаксис).

Подсчитаем сумму элементов массива.

Императивный стиль

const sum = (arr) => {
  let result = 0; 
  for (let i = 0; i < arr.length; i++) {
    result += arr[i];
  }  
  return result;
};

Императивный стиль сам по себе неплох, но чем больше кода, тем сложнее его читать и возрастает вероятность допустить ошибку. Кроме того, сложность такого подхода в том, что мы объясняем компьютеру вместо того, что мы хотим сделать, как это нужно делать.

Декларативный стиль

const sum = (arr) => arr.reduce((total, item) => total += item, 0);

Так наш код выглядит намного проще, короче и понятнее. В таком коде сложнее сделать ошибку, его легче изменять и обслуживать. Мы говорим компьютеру что мы хотим сделать, а не как это делать.

Обратите внимание

Если вас в первую очередь интересует производительность, то в зависимости от размера датасета результаты могут различаться, ознакомьтесь со следующей информацией  относительно javascript циклов: но небольшим наборам данных информация здесь, а вот здесь можно посмотреть производительность разных циклов на объемах от 100 до 1000000 объектов.

Функции map, filter, reduce как замена обычным javascript циклам.

Методы в Javascript ES6 заменяющие циклы

Array.map()

Перебирает все элементы массива и возвращает новое значение.
С циклами:

var names = ["Jack", "Jecci", "Ram", "Tom"];
var upperCaseNames = [];
for(let i=0, totalNames = names.length; i< totalNames ; i= i +1) {
    upperCaseNames = names[i].toUpperCase();
}

Без:

const names = ["Jack", "Jecci", "Ram", "Tom"];
const upperCaseNames = names.map(name => name.toUpperCase());

Стоит учесть

При использовании map, вы не сможете обращаться к операторам break, continue и return во время итерации. Возможно в таком случае вам пригодятся методы every или some. Почитать о них можно в этой статье.

Array.forEach()

Перебирает все элементы и выполняет действие.

С циклами:

function print(name) {
   console.log(name);
}
var names = ["Jack", "Jecci", "Ram", "Tom"];
for(let i=0, totalNames = names.length; i< totalNames ; i= i +1) {
    print(names[i])
}

Без циклов:

const names = ["Jack", "Jecci", "Ram", "Tom"];
names.forEach(name=> print(name));

Array.filter()

Возвращает только элементы удовлетворяющие условию.

С циклами:

function isOdd(n) {
   return n %2;
}
var numbers = [1,2,3,4,5];
var odd = [];
for(let i=0, total = numbers.length; i< total ; i= i +1) {
   let number = numbers[i];
   if( isOdd(number) ) {
      odd.push(number);
   }
}

Без циклов:

var numbers = [1,2,3,4,5, 6, 7]
var odd = numbers.filter(n => n%2); // single line

Array.reduce()

Метод reduce() применяет функцию reducer к каждому элементу массива (слева-направо), возвращая одно результирующее значение.

С циклами:

var numbers = [1,2,3,4,5]
var result = 0;
for(let i=0, total = numbers.length; i< total ; i= i +1) {
   result = result + numbers[i];
}

Без циклов:

var numbers = [1,2,3,4,5,6,7];
function sum(accumulator, currentValue){
   return accumulator + currentValue;
}
var initialVal = 0;
var result = numbers.reduce(sum, initialVal);

Код без циклов можно упростить:

var numbers = [1,2,3,4,5,6,7, 10];
var result = numbers.reduce((acc, val)=> acc+val, 0);

Эта статья была интересна вам?