JavaScript: .forEach () ve .map () arasındaki fark


116

Bunun gibi pek çok konu olduğunu biliyorum. Ve temelleri biliyorum: .forEach()orijinal dizide ve yenisinde çalışır .map().

Benim durumumda:

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);

Ve bu çıktı:

[ -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 ]

Kullanarak neden anlayamıyorum practicedeğişikliklerin değer biçin undefined.
Bu aptalca bir soru ise özür dilerim, ama bu dilde oldukça yeniyim ve şimdiye kadar bulduğum cevaplar beni tatmin etmedi.


49
Bu kadar basit: .map yeni bir dizi döndürür , ancak .forEach hiçbir şey döndürmez . Temel olarak, önceki dizinin değiştirilmiş bir biçimini elde etmek istiyorsanız, kullanırsınız .map, istemiyorsanız kullanırsınız .forEach.
user4642212


@Xufox - Bu konuyu yenisini oluşturmadan önce yeniden yazdım ama cevap beni tatmin etmedi.
DzikiChrzan

Sadece seni tatmin etmediğini söyleme. Sorunuza tam olarak nasıl cevap vermiyor (tüm cevapları okudunuz mu?)? Önerilen yinelenen hedef tarafından kapsanmayan özel sorunuz nedir?
user4642212

@Xufox Bu soru kendiliğinden gerçekleştirilen işlevlerle ilgilidir ve standartlaştırılmış ES5 işlevleriyle ilgili değildir.
dürtmek

Yanıtlar:


147

Tek ve aynı değiller. Farkı açıklayayım.

forEach: Bu, bir liste üzerinde yinelenir ve her liste üyesine bazı yan etkilerle bazı işlemler uygular (örnek: her liste öğesini veritabanına kaydetme)

map: Bu, bir listeyi yineler, bu listenin her üyesini dönüştürür ve dönüştürülen üyelerle aynı boyutta başka bir listeyi döndürür (örnek: dizelerin listesini büyük harfe dönüştürme)

Referanslar

Array.prototype.forEach () - JavaScript | MDN

Array.prototype.map () - JavaScript | MDN


5
Ve Xufox'un dediği gibi - .forEach hiçbir şey döndürmez, durum bu. Yardım için teşekkürler! Bu yanıtı 10 dakika içinde işaretleyeceğim.
DzikiChrzan

1
harita dönüş listesi ve her biri için değil. Tamam
Ashad Nasim

62
  • Array.forEach "Sağlanan bir işlevi dizi öğesi başına bir kez çalıştırır."

  • Array.map "Bu dizideki her öğede sağlanan bir işlevi çağırmanın sonuçlarıyla yeni bir dizi oluşturur."

Yani forEachaslında hiçbir şey döndürmez. Sadece her dizi elemanı için işlevi çağırır ve sonra yapılır. Böylece, adı verilen işlevin içinde ne iade ederseniz edin, basitçe atılır.

Öte yandan, mapbenzer şekilde her bir dizi öğesi için işlevi çağıracak, ancak dönüş değerini atmak yerine, onu yakalayacak ve bu dönüş değerlerinden yeni bir dizi oluşturacaktır.

Bu aynı zamanda , kullandığınız mapher yerde kullanabileceğiniz anlamına gelir, forEachancak yine de bunu yapmamanız gerekir, böylece geri dönüş değerlerini herhangi bir amaç olmadan toplamazsınız. İhtiyacınız yoksa onları toplamamak daha etkilidir.


Not: 2015'te, özellikle eski bir tarayıcıyı (IE8 veya 9) desteklemek için bir çoklu doldurma gerekli forEacholsaydı bundan "daha verimli" olacağı tartışılabilirdi . Hiçbir şeye dönüşü tayin etmenize gerek yok; dönüş değeri , dönüşü atanmadığında iadelerden hemen sonra çöpün toplanmasını sağlamalıdır . mapforEachmapmapmap
cowbert

3
@cowbert Sırf bir şey hemen çöp toplandığı için, bu gerekli olan tahsisler tarafından vurulmadığınız anlamına gelmez. Dolayısıyla forEach, kavramsal olarak yine de daha verimli olacak ve sonuç toplamanız gerekmeyen görevler için daha uygun olacaktır. Ve seni bilmiyorum ama 2015'te artık IE8 için geliştirme yapmıyordum (ki btw de desteklemiyordu map); ve IE9 + desteği forEach. Ve aslında cevabımdan bir ay sonra, Microsoft bu tarayıcılar için desteği sona erdirdi.
dürtmek

Hem forEach hem de map öğelerinin aynı sırayla işlenmesi garantili mi?
Quentin 2

1
Quentin2 @ Evet, aynı zamanda, her iki işlevi eşzamanlı, yani mapve forEachbütün dizi aracılığıyla devreye edilmiş ve geri arama her biri için adı olmuştur kez aramalar sadece dönecektir.
dürtmek

25
+ ---------------- + -------------------------------- ----- + --------------------------------------- +
| | foreach | harita |
+ ---------------- + -------------------------------- ----- + --------------------------------------- +
| İşlevsellik | Her bir | Verilen "dönüştürme" |
| | dizinin öğesi | her elemanın "kopyası" |
+ ---------------- + -------------------------------- ----- + --------------------------------------- +
| Dönüş değeri | Tanımsız döndürür | Yeni diziyi dönüştürülmüş |
| | | orijinal diziyi geri bırakan elemanlar |
| | | değişmemiş |
+ ---------------- + -------------------------------- ----- + --------------------------------------- +
| Tercihli | Gibi dönüşümsüz gerçekleştirmek | | Çıktısını içeren dizi elde ediliyor
| kullanım senaryosu | her elemanın işlenmesi. | her eleman üzerinde bazı işlemler yapıldı |
| ve örnek | | dizinin. |
| | Örneğin, tüm öğeleri | |
| | veritabanı | Örneğin, | dizisi elde ediliyor.
| | | her dizenin uzunlukları |
| | | dizi |
+ ---------------- + -------------------------------- ----- + --------------------------------------- +

Lütfen yayınınızı düzenleyin ve resimler yerine gerçek metni gösterin. Başkaları resminizden kopyalayıp yapıştıramaz veya resminizin içinde arama yapamaz veya resimdeki metin içeriğini iyileştirmeye yardımcı olamaz. Ayrıntılar için buraya bakın. Teşekkür ederim.
Pang

2
Bu, ASCII sanat tabloları çizmenize yardımcı olabilir: webapps.stackexchange.com/q/6700/126269
Pang


7

forEach: Bir Array öğesinin öğeleri üzerinde bir eylem gerçekleştirmek istiyorsanız ve bu, for döngüsü kullandığınızla aynıysa. Bu yöntemin sonucu bize bir çıktı alımı sağlamaz, sadece öğeler arasında döngü oluşturur.

map: Bir dizinin öğeleri üzerinde bir eylem gerçekleştirmek ve ayrıca eyleminizin çıktısını bir Dizi olarak depolamak istiyorsanız. Bu, her yinelemeden sonra sonucu döndüren bir işlev içindeki for döngüsüne benzer.

Bu yardımcı olur umarım.


5

Aradaki fark, geri döndüklerinde yatıyor. Yürütmeden sonra:

arr.map()

işlenmiş işlevden kaynaklanan bir dizi öğe döndürür; süre:

arr.forEach()

tanımsız döndürür.


5

Performans Analizi For loop'lar, bir dizideki öğe sayısı arttıkça map veya foreach'den daha hızlı çalışır.

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');

İşte bilgisayarımdaki sonuç:map: 1642ms forEach: 885ms for: 748ms
Flavio Vilante


1

Dikkat edilmesi gereken bir şey, foreach'in ilklendirilmemiş değerleri atlaması, ancak haritanın atlamamasıdır.

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

ForEach () ve Map () arasındaki fark

her biri için() sadece öğeler arasında döngü oluşturur. Dönüş değerlerini atar ve her zaman tanımsız olarak döner.Bu yöntemin sonucu bize bir çıktı vermez.

map () öğeleri boyunca döngü, bellek ayırır ve ana diziyi yineleyerek dönüş değerlerini depolar

Misal:

   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 () forEach () 'den daha hızlıdır


0

ForEach dönmezken Map örtük olarak döndürülür.

Bu nedenle, bir JSX uygulamasını kodlarken, içeriği React'te görüntülemek için neredeyse her zaman forEach yerine map kullanırsınız .


0

forEach () :

geri dönüş değeri : tanımsız

originalArray: yöntem çağrısından sonra değiştirildi

harita () :

dönüş değeri: yeni dizi, çağıran dizideki her öğede sağlanan bir işlevi çağırmanın sonuçlarıyla doldurulur

originalArray: yöntem çağrısından sonra değiştirilmez

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.