Есть ли случаи, когда array.forEach () лучше, чем array.map ()? - PullRequest
0 голосов
/ 26 января 2019

В Javascript я читал разные статьи о том, когда использовать forEach против map в массиве.Общее согласие заключается в том, что если вы просто хотите прочитать каждый элемент массива, используйте forEach.Если вы действительно хотите изменить данные, используйте map.Некоторые даже заходят так далеко, говоря, что всегда используйте map, когда это возможно, это безопаснее и быстрее.

В моем случае все, что я хочу сделать, - это обновить отдельное свойство в каждом элементе.

var arr = [{
  firstName: 'Tom',
  lastName: 'Washington',
  fullName: undefined
}, {
  firstName: 'Bill',
  lastName: 'Smith',
  fullName: undefined
}, {
  firstName: 'Jim',
  lastName: 'Jones',
  fullName: undefined
}];

// arr.forEach((person) => {
//   person.fullName = `${person.lastName}, ${person.firstName}`;
// });

var newArr = arr.map((person) => {
  return {...person, fullName: `${person.lastName}, ${person.firstName}`};
});

console.log(arr);
console.log(newArr);

Что мне трудно понять, почему предпочтительнее подход map?Используя forEach, я обновляю данные на месте.С map я создаю новый массив со всеми новыми элементами.Я понимаю, что это предпочтительнее, если вы хотите сохранить исходный массив, или теперь у вас есть возможность сделать цепочку, если вы хотите выполнить дополнительные операции над массивом.Но если мне все равно, почему forEach не предпочтительнее?

Ответы [ 3 ]

0 голосов
/ 26 января 2019

Скорее всего, они называют map "безопаснее", потому что это соответствует функциональной модели программирования.В функциональном программировании большинство, если не все, данные являются неизменяемыми;программирование - это создание новых данных на основе существующих данных, а не их изменение на месте.

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

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

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

Тем не менее, если выЕсли вы не используете функциональный стиль, и вы не создаете библиотеку для перераспределения, то действие на расстоянии всегда будет рискованным, а частично функциональное функционирование очень мало для вас, так что вы должны просто выбрать правильныйинструмент для работы;forEach только для чтения или для изменения на месте, map для создания нового массива.

Последнее замечание: теоретически, map может сделать код быстрее, несмотря на создание новых массивов.Когда массив гарантированно будет создан и уничтожен в одной функции, оптимизатору JIT будет проще с анализом времени жизни, анализом типичного содержимого и т. Д., И он может предположительно:

  1. Полностью оптимизировать промежуточные массивы(пять map с может создать только один новый массив)
  2. Специализировать массив по содержимому, длине и т. д. (возможно с массивами, полученными извне, но сложнее сделать последовательно)

Я бы не стал рассчитывать на такую ​​оптимизацию с map (не решайте, какую именно использовать на этой основе), но реальные функциональные языки получают преимущества, подобные этой, благодаря гарантиям неизменности, которые они обеспечивают, и механизмы JIT JavaScript могут воспользоватьсятех же самых «гарантий», когда они могут наблюдать, к которым они присоединяются на практике.

0 голосов
/ 26 января 2019

Просто на примере.

forEach() может быть предпочтительнее, когда вы не пытаетесь изменить данные в вашем массиве, но вместо этого хотите просто что-то с этим сделать - например, сохранить их вбаза данных или выход из нее:

let arr = ['a', 'b', 'c', 'd'];
arr.forEach((letter) => {
    console.log(letter);
});


// a
// b
// c
// d

И map() может быть предпочтительным при изменении или изменении данных.Он не только быстрее, но и возвращает новый массив.Это означает, что мы можем делать классные вещи, такие как сцепление с другими методами (map(), filter(), reduce() и т. Д.)

    let arr = [1, 2, 3, 4, 5];
    let arr2 = arr.map(num => num * 2).filter(num => num > 5);
    
    // arr2 = [6, 8, 10]

То, что мы делаем выше, - это сначала сопоставление arr и умножение каждого элемента на время массива 2. После этого мы фильтруем массив и сохраняем только те элементы, которыебольше 5. Это оставляет нам окончательный arr2 из [6,8,10].

0 голосов
/ 26 января 2019

array.forEach просто перебирает массив, а array.map () создает копию этого массива, создавая функцию обратного вызова для каждого элемента, поэтому вы можете сделать что-то вроде:

array.map (x => x * 2)

теперь вы получаете новый массив с каждым значением, умноженным на 2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...