JavaScript: różnica między .forEach () i .map ()


116

Wiem, że takich tematów było wiele. I znam podstawy: .forEach()działa na oryginalnej tablicy i .map()na nowej.

W moim przypadku:

function practice (i){
    return i+1;
};

var a = [ -1, 0, 1, 2, 3, 4, 5 ];
var b = [ 0 ];
var c = [ 0 ];
console.log(a);
b = a.forEach(practice);
console.log("=====");
console.log(a);
console.log(b);
c = a.map(practice);
console.log("=====");
console.log(a);
console.log(c);

A to jest wyjście:

[ -1, 0, 1, 2, 3, 4, 5 ]
=====
[ -1, 0, 1, 2, 3, 4, 5 ]
undefined
=====
[ -1, 0, 1, 2, 3, 4, 5 ]
[ 0, 1, 2, 3, 4, 5, 6 ]

Nie mogę zrozumieć, dlaczego użycie practicezmienia wartość bdo undefined.
Przykro mi, jeśli to głupie pytanie, ale jestem całkiem nowy w tym języku, a odpowiedzi, które znalazłem do tej pory, nie zadowalały mnie.


49
To takie proste: .map zwraca nową tablicę , ale .forEach nic nie zwraca . Zasadniczo, jeśli chcesz uzyskać zmodyfikowaną postać poprzedniej tablicy, użyj .map, jeśli nie chcesz tego, użyj .forEach.
user4642212


@Xufox - przerobiłem ten temat przed utworzeniem nowego, ale odpowiedź mnie nie satysfakcjonowała.
DzikiChrzan

Nie mów, że to cię nie satysfakcjonowało. Jak dokładnie nie odpowiada na twoje pytanie (czy przeczytałeś wszystkie odpowiedzi?)? Jakie jest Twoje konkretne pytanie, którego nie obejmuje proponowany zduplikowany cel?
user4642212

@Xufox To pytanie dotyczy funkcji zaimplementowanych samodzielnie i tak naprawdę nie dotyczy standardowych funkcji ES5.
szturchnij

Odpowiedzi:


147

Nie są jednym i tym samym. Pozwól mi wyjaśnić różnicę.

forEach: Powoduje to iterację po liście i zastosowanie pewnych operacji z efektami ubocznymi do każdego elementu listy (przykład: zapisywanie każdego elementu listy do bazy danych)

map: Powoduje iterację po liście, przekształca każdego członka tej listy i zwraca inną listę o tym samym rozmiarze z przekształconymi składowymi (przykład: przekształcanie listy ciągów na wielkie litery)

Bibliografia

Array.prototype.forEach () - JavaScript | MDN

Array.prototype.map () - JavaScript | MDN


5
I jak powiedział Xufox - .forEach nic nie zwraca, tak jest. Dzięki za pomoc! Zaznaczę tę odpowiedź za 10 minut.
DzikiChrzan

1
map return list i forEach not. OK
Ashad Nasim

62
  • Array.forEach „Wykonuje podaną funkcję raz na element tablicy”.

  • Array.map „Tworzy nową tablicę z wynikami wywołania podanej funkcji na każdym elemencie tej tablicy”.

Więc forEachtak naprawdę nic nie zwraca. Po prostu wywołuje funkcję dla każdego elementu tablicy i gotowe. Więc cokolwiek zwrócisz w ramach tej wywołanej funkcji, jest po prostu odrzucane.

Z drugiej strony, w mappodobny sposób wywoła funkcję dla każdego elementu tablicy, ale zamiast odrzucać jej wartość zwracaną, przechwyci ją i utworzy nową tablicę tych zwracanych wartości.

To oznacza również, że mogłaby używać mapgdziekolwiek używasz forEachale nadal nie należy robić, aby nie zbierać wartości zwracanych bez jakiegokolwiek celu. Po prostu skuteczniej jest ich nie zbierać, jeśli ich nie potrzebujesz.


Uwaga: w 2015 r. Można by się spierać, że forEachbyłoby to „bardziej wydajne” niż w mapprzypadku, gdyby do obsługi forEachstarszej przeglądarki (IE8 lub 9) wymagany był wypełniacz polyfill . Nie musisz przypisywać zwrotu mapniczego; wartość zwracana powinna zostać usunięta natychmiast po mapzwróceniu, gdy zwrot mapnie jest przypisany.
cowbert

3
@cowbert Tylko dlatego, że coś jest natychmiast zbierane jako śmieci, nie oznacza to, że nie jesteś uderzony przez alokacje, które były konieczne. Więc forEachbędzie koncepcyjnie być jeszcze bardziej skuteczne i lepiej nadaje się do zadań, gdzie nie potrzeba gromadzenia wyników. I nie wiem jak wy, ale w 2015 roku nie tworzyłem już dla IE8 (co zresztą też nie wspierało map); i IE9 + forEach. I faktycznie miesiąc po mojej odpowiedzi Microsoft zakończył wsparcie dla tych przeglądarek.
szturchnij

Czy obie opcje forEach i map będą przetwarzać elementy w tej samej kolejności?
Quentin 2

1
@ Quentin2 Tak, również obie funkcje są synchroniczne, więc mapi forEachwywołanie zwróci tylko raz cała tablica została przelotowe i zwrotna została wywołana dla każdego.
poke

25
+ ---------------- + -------------------------------- ----- + --------------------------------------- +
| | foreach | mapa |
+ ---------------- + -------------------------------- ----- + --------------------------------------- +
| Funkcjonalność | Wykonuje daną operację na każdym | Wykonuje zadaną "transformację" na |
| | element tablicy | "kopia" każdego elementu |
+ ---------------- + -------------------------------- ----- + --------------------------------------- +
| Wartość zwracana | Zwraca undefined | Zwraca nową tablicę z przekształconą |
| | | elementy pozostawiające oryginalną tablicę |
| | | niezmienione |
+ ---------------- + -------------------------------- ----- + --------------------------------------- +
| Preferrable | Wykonywanie nietransformacji, takich jak | Uzyskiwanie tablicy zawierającej wyjście |
| scenariusz użycia | przetwarzanie na każdym elemencie. | trochę przetwarzania wykonanego na każdym elemencie |
| i przykład | | tablicy. |
| | Na przykład zapisywanie wszystkich elementów w | |
| | baza danych | Na przykład uzyskanie tablicy |
| | | długości każdego ciągu w |
| | | tablica |
+ ---------------- + -------------------------------- ----- + --------------------------------------- +

Proszę edytować swój post i pokazać rzeczywisty tekst zamiast obrazów. Inni nie mogą kopiować i wklejać z Twojego obrazu, wyszukiwać w Twoim obrazie ani pomagać w poprawianiu zawartości tekstowej w obrazie. Zobacz szczegóły. Dziękuję Ci.
Pang

2
Może to pomóc w rysowaniu tabel z grafiką
Pang


7

forEach: Jeśli chcesz wykonać akcję na elementach Array i jest to takie samo, jak w przypadku pętli for. Wynik tej metody nie daje nam wyjścia kupna tylko pętla przez elementy.

map: Jeśli chcesz wykonać akcję na elementach tablicy, a także chcesz zapisać dane wyjściowe akcji w tablicy. Jest to podobne do pętli for w funkcji, która zwraca wynik po każdej iteracji.

Mam nadzieję że to pomoże.


5

Różnica polega na tym, co zwracają. Po wykonaniu:

arr.map()

zwraca tablicę elementów wynikających z przetwarzanej funkcji; podczas:

arr.forEach()

zwraca undefined.


5

Analiza wydajności Pętle For działają szybciej niż mapowanie lub foreach, gdy liczba elementów w tablicy wzrasta.

let array = [];
for (var i = 0; i < 20000000; i++) {
  array.push(i)
}

console.time('map');
array.map(num => {
  return num * 4;
});
console.timeEnd('map');


console.time('forEach');
array.forEach((num, index) => {
  return array[index] = num * 4;
});
console.timeEnd('forEach');

console.time('for');
for (i = 0; i < array.length; i++) {
  array[i] = array[i] * 2;

}
console.timeEnd('for');

Oto wynik na moim komputerze:map: 1642ms forEach: 885ms for: 748ms
Flavio Vilante


1

Należy zwrócić uwagę na to, że foreach pomija niezainicjowane wartości, podczas gdy map nie.

var arr = [1, , 3];

arr.forEach(function(element) {
    console.log(element);
});
//Expected output: 1 3

console.log(arr.map(element => element));
//Expected output: [1, undefined, 3];

0

Różnica między forEach () i map ()

dla każdego() po prostu elementy. Odrzuca zwracane wartości i zawsze zwraca undefined. Rezultat tej metody nie daje nam wyniku.

map () pętla przez elementy przydziela pamięć i przechowuje wartości zwracane przez iterację tablicy głównej

Przykład:

   var numbers = [2,3,5,7];

   var forEachNum = numbers.forEach(function(number){
      return number
   })
   console.log(forEachNum)
   //output undefined

   var mapNum = numbers.map(function(number){
      return number
   })
   console.log(mapNum)
   //output [2,3,5,7]

map () jest szybsze niż forEach ()



0

forEach () :

zwracana wartość: niezdefiniowana

originalArray: zmodyfikowana po wywołaniu metody

mapa () :

zwracana wartość: nowa Tablica wypełniona wynikami wywołania podanej funkcji na każdym elemencie wywołującej tablicy

originalArray: nie modyfikowana po wywołaniu metody

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.