Для каждого по массиву в JavaScript

Если вы пишете JavaScript даже в течение короткого промежутка времени, вы, вероятно, все еще знаете, как быстро меняется язык. Учитывая все эти изменения, это означает, что существует несколько способов выполнения одной и той же функции. В этом случае я имею в виду цикл по массивам с использованием конструкции for-each. Итак, как лучше всего это сделать? Этот вопрос зависит от нескольких вещей, например, какую версию JS вы используете, можете ли вы использовать методы экземпляра и т. Д. В этой статье я исследую число

Если вы пишете JavaScript даже в течение короткого промежутка времени, вы, вероятно, все еще знаете, как быстро меняется язык. Учитывая все эти изменения, это означает, что существует несколько способов выполнения одной и той же функции. В этом случае я имею в виду цикл по массивам с использованием конструкции for-each .

Итак, как лучше всего это сделать? Этот вопрос зависит от нескольких вещей, например, какую версию JS вы используете, можете ли вы использовать методы экземпляра и т. Д. В этой статье я исследую несколько способов перебора массивов в JS.

Метод массива forEach

Широко поддерживаемым методом (за исключением IE 8, что неудивительно) является метод Array.prototype.forEach Он работает, принимая функцию обратного вызова с параметрами currentValue , index и array . Во многих случаях используются только параметры currentValue и index .

Вот пример:

 let items = ['one', 'two', 'three', 'four']; 
 items.forEach(function(val, idx) { 
 console.log(`${idx}: ${val}`); 
 }); 
 
 // Output: 
 // 
 // 0: one 
 // 1: two 
 // 2: three 
 // 3: four 

Это отличный метод благодаря своей простоте и чистому синтаксису, хотя у него есть некоторые недостатки. В частности, трудно выйти из этого цикла, в отличие от встроенного for где вы можете использовать ключевое слово break С forEach вы должны выбросить исключение, чтобы выйти из цикла раньше.

Как указано в документации MDN , если вам нужно выйти из forEach , то этот метод - неправильный инструмент. В этом случае лучшими вариантами будут:

  • Встроенный for (подробно описан ниже)
  • Встроенный for-of (подробно описан ниже)
  • Array.prototype.every()
  • Array.prototype.some()
  • Array.prototype.find()
  • Array.prototype.findIndex()

Array.prototype.* Могут выходить из своих циклов, возвращая истинное значение, которое сообщает циклу, следует ли ему продолжить.

Метод forEach хорош, когда у вас есть очень простые требования к циклу, и вам не нужен большой контроль над фактическим поведением цикла. Однако за эту простоту приходится платить. Это примерно на 95% медленнее, чем встроенный for , но для большинства людей это замедление будет незначительным.

Встроенный цикл

Встроенный for (также известный как простой for ), вероятно, является наиболее известным из вариантов, поскольку он работает в JavaScript так же, как и во многих других языках. Синтаксис следующий:

 let items = ['one', 'two', 'three', 'four']; 
 for (let i = 0; i < items.length; ++i) { 
 console.log(`${i}: ${items[i]}`); 
 } 
 
 // Output: 
 // 
 // 0: one 
 // 1: two 
 // 2: three 
 // 3: four 

Такой for имеет ряд преимуществ:

  • Это знакомо большинству программистов
  • Ключевые слова продолжения цикла управления break и continue
  • Контролировать направление счетчика (через ++i или --i ) и скорость (т.е. i+2 )
  • Частичный цикл (т.е. for (let i = 0; i < items.length/2; ++i) )

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

Обратите внимание, что в приведенном выше примере предполагается, что вы используете ES6 JavaScript, в противном случае вам нужно будет объявить i с помощью var и вне самого цикла.

Встроенный цикл for-in

Вероятно, наиболее часто неправильно понимаемая форма цикла в JavaScript

  • это цикл for-in На первый взгляд кажется, что вы можете использовать это для циклического перебора каждого индекса в массиве, но на самом деле он предназначен для перебора имен перечислимых свойств объекта, а не обязательно только индексов.

Например, вот как он используется с массивами:

 let items = ['one', 'two', 'three', 'four']; 
 for (let i in items) { 
 console.log(`${i}: ${items[i]}`); 
 } 
 
 // Output: 
 // 
 // 0: one 
 // 1: two 
 // 2: three 
 // 3: four 

И вот как он предназначен для использования с объектами:

 let obj = {hi: 'bye', one: 'two', foo: 'bar'}; 
 for (let o in obj) { 
 console.log(`${o}: ${obj[o]}`); 
 } 
 
 // Output 
 // 
 // hi: bye 
 // one: two 
 // foo: bar 

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

Если вы хотите перебрать массив с таким синтаксисом, for-of , что является предметом рассмотрения в следующем разделе.

Встроенный цикл for-of

for-of имеют синтаксис, очень похожий на синтаксис for-in , который мы только что видели. Однако их главное отличие состоит в том, что он выполняет итерацию по итерируемым объектам (таким как строки, массивы, карты, наборы и т. Д.), Тогда как for-in выполняет итерацию по всем перечислимым свойствам объекта, не являющимся символом.

На практике это выглядит так:

 let items = ['one', 'two', 'three', 'four']; 
 for (let i of items) { 
 console.log(i); 
 } 
 
 // Output: 
 // 
 // one 
 // two 
 // three 
 // four 

Обратите внимание, что i больше не является индексом, а представляет собой фактическое значение массива. И поскольку он работает только с итерациями, мы больше не можем использовать объект:

 let obj = {hi: 'bye', one: 'two', foo: 'bar'}; 
 for (let o of obj) { 
 console.log(o); 
 } 
 
 // Output: 
 // 
 // TypeError: obj is not iterable 

С точки зрения синтаксиса и функциональности это своего рода компромисс между Array.forEach и встроенным for поскольку синтаксис чище, чем простой for , и он по-прежнему позволяет использовать ключевые слова "управления" циклом, такие как break и continue , в отличие от forEach .

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

 function* myWords() { 
 yield 'foo'; 
 yield 'bar'; 
 yield 'baz'; 
 } 
 
 for (let w of myWords()) { 
 console.log(w); 
 } 
 
 // Output: 
 // 
 // foo 
 // bar 
 // baz 

Заключение

Как видите, существует довольно много способов выполнить цикл for-each над массивом в JavaScript, и выбранная вами конструкция во многом зависит от того, чего вы хотите достичь, и от вашего конкретного варианта использования.

В этой статье мы увидели, как перебирать массивы с помощью Array.forEach , встроенных циклов for for-in и for-of . Не стесняйтесь оставлять комментарии ниже с любыми критическими замечаниями или улучшениями, которые вы видите.

comments powered by Disqus