JavaScript має кілька зручних методів, які допомагають нам переглядати наші масиви. Два найбільш часто використовувані для ітерації - Array.prototype.map()
та Array.prototype.forEach()
.
Але я думаю, що вони залишаються трохи незрозумілими, особливо для початківців. Тому що вони обидва роблять ітерацію і виводять щось. Отже, в чому різниця?
У цій статті ми розглянемо наступне:
- Визначення
- Повертається значення
- Можливість ланцюга інших методів
- Змінюваність
- Швидкість продуктивності
- Заключні думки
Визначення
map
Метод приймає функцію в якості параметра. Потім він застосовує його до кожного елемента і повертає абсолютно новий масив, заповнений результатами виклику наданої функції.
Це означає, що він повертає новий масив, що містить зображення кожного елемента масиву. Завжди повертається однакова кількість предметів.
const myAwesomeArray = [5, 4, 3, 2, 1] myAwesomeArray.map(x => x * x) // >>>>>>>>>>>>>>>>> Output: [25, 16, 9, 4, 1]
Подібно map
, forEach()
метод отримує функцію як аргумент і виконує її один раз для кожного елемента масиву. Однак замість того, щоб повернути новий масив типу map
, він повертається undefined
.
const myAwesomeArray = [ { id: 1, name: "john" }, { id: 2, name: "Ali" }, { id: 3, name: "Mass" }, ] myAwesomeArray.forEach(element => console.log(element.name)) // >>>>>>>>> Output : john // Ali // Mass
1. Повертається значення
Перша різниця між map()
і forEach()
- це повертається значення. У forEach()
методі повертає undefined
і map()
повертає новий масив з перетвореними елементами. Навіть якщо вони виконують одну і ту ж роботу, повертається вартість залишається іншою.
const myAwesomeArray = [1, 2, 3, 4, 5] myAwesomeArray.forEach(x => x * x) //>>>>>>>>>>>>>return value: undefined myAwesomeArray.map(x => x * x) //>>>>>>>>>>>>>return value: [1, 4, 9, 16, 25]
2. Можливість ланцюга інших методів
Друга відмінність між цими методами масивів - це той факт, що map()
можна застосувати до мережі. Це означає , що ви можете прикріпитися reduce()
, sort()
, filter()
і так далі після виконання map()
методу на масиві.
Це те, з чим не можна впоратися, forEach()
бо, як можна здогадатися, воно повертається undefined
.
const myAwesomeArray = [1, 2, 3, 4, 5] myAwesomeArray.forEach(x => x * x).reduce((total, value) => total + value) //>>>>>>>>>>>>> Uncaught TypeError: Cannot read property 'reduce' of undefined myAwesomeArray.map(x => x * x).reduce((total, value) => total + value) //>>>>>>>>>>>>>return value: 55
3. Змінюваність
Загалом, слово "мутувати" означає змінювати, чергувати, модифікувати або перетворювати. І у світі JavaScript це має таке саме значення.
Змінюваний об'єкт - це об'єкт, стан якого може бути змінений після його створення. Отже, що стосується змінності forEach
та map
щодо неї?
Ну, згідно з документацією MDN:
forEach()
не мутує масив, на якому він викликається. (Однак callback
може зробити це).
map()
не мутує масив, до якого він викликаний (хоча callback
, якщо його викликати, може це зробити).
JavaScript дивний .

Тут ми бачимо дуже подібне визначення, і всі ми знаємо, що вони обидва отримують callback
аргумент. Отже, хто з них покладається на незмінність?
Ну, на мою думку, це визначення не зрозуміле. І щоб знати, що не мутує вихідний масив, спочатку потрібно перевірити, як працюють ці два методи.
map()
Метод повертає абсолютно новий масив з перетвореними елементами і тим же кількістю даних. У випадку forEach()
, навіть якщо він повернеться undefined
, він буде мутувати вихідний масив за допомогою callback
.
Тому ми чітко бачимо, що він map()
покладається на незмінність і forEach()
є мутаторним методом.
4. Швидкість продуктивності
Що стосується швидкості роботи, вони трохи відрізняються. Але, чи це важливо? Ну, це залежить від різних речей, таких як ваш комп’ютер, обсяг даних, з якими ви маєте справу тощо.
Ви можете перевірити це самостійно за допомогою цього прикладу нижче або за допомогою jsPerf, щоб побачити, що швидше.
const myAwesomeArray = [1, 2, 3, 4, 5] const startForEach = performance.now() myAwesomeArray.forEach(x => (x + x) * 10000000000) const endForEach = performance.now() console.log(`Speed [forEach]: ${endForEach - startForEach} miliseconds`) const startMap = performance.now() myAwesomeArray.map(x => (x + x) * 10000000000) const endMap = performance.now() console.log(`Speed [map]: ${endMap - startMap} miliseconds`)
Заключні думки
Як завжди, вибір між map()
і forEach()
буде залежати від вашого випадку використання. Якщо ви плануєте змінити, чергувати чи використовувати дані, вам слід вибрати map()
, оскільки він повертає новий масив із перетвореними даними.
Але якщо вам не знадобиться повернутий масив, не використовуйте map()
- замість цього використовуйте forEach()
або навіть for
цикл.
Сподіваємось, ця публікація прояснить відмінності між цими двома методами. Якщо розбіжностей є більше, будь ласка, поділіться ними у розділі коментарів, інакше дякую за прочитання.
Прочитайте більше моїх статей у моєму блозі
Фото Франка В. на Unsplash