Satu-satunya perbedaan yang saya lihat di map dan foreach map
adalah mengembalikan array dan forEach
tidak. Namun, saya bahkan tidak mengerti baris terakhir dari forEach
metode " func.call(scope, this[i], i, this);
". Misalnya, bukankah " this
" dan " scope
" merujuk ke objek yang sama dan bukan this[i]
dan i
merujuk ke nilai saat ini dalam pengulangan?
Saya melihat di posting lain seseorang berkata "Gunakan forEach
saat Anda ingin melakukan sesuatu berdasarkan setiap elemen daftar. Anda mungkin menambahkan sesuatu ke halaman, misalnya. Pada dasarnya, ini bagus untuk saat Anda menginginkan" efek samping ". Saya tidak tahu apa yang dimaksud dengan efek samping.
Array.prototype.map = function(fnc) {
var a = new Array(this.length);
for (var i = 0; i < this.length; i++) {
a[i] = fnc(this[i]);
}
return a;
}
Array.prototype.forEach = function(func, scope) {
scope = scope || this;
for (var i = 0, l = this.length; i < l; i++) {
func.call(scope, this[i], i, this);
}
}
Akhirnya, apakah ada kegunaan nyata untuk metode ini dalam javascript (karena kami tidak memperbarui database) selain untuk memanipulasi angka seperti ini:
alert([1,2,3,4].map(function(x){ return x + 1})); //this is the only example I ever see of map in javascript.
Terima kasih atas balasannya.
sumber
map
danforEach
? Yang saya dapatkan dari Google hanyalah spesifikasi penggunaan dan tutorialnya.Jawaban:
Perbedaan penting antara
map
danforEach
dalam contoh Anda adalah yangforEach
beroperasi pada elemen larik asli, sedangkanmap
secara eksplisit mengembalikan larik baru sebagai hasilnya.Dengan
forEach
Anda mengambil beberapa tindakan dengan - dan secara opsional mengubah - setiap elemen dalam larik asli. TheforEach
Metode menjalankan fungsi yang Anda berikan untuk setiap elemen, tetapi mengembalikan apa-apa (undefined
). Di sisi lain,map
menelusuri array, menerapkan fungsi ke setiap elemen, dan memancarkan hasilnya sebagai array baru ."Efek samping" dengan
forEach
adalah bahwa array asli sedang diubah. "Tanpa efek samping"map
artinya, dalam penggunaan idiomatik, elemen array asli tidak berubah; array baru adalah pemetaan satu-ke-satu dari setiap elemen dalam array asli - transformasi pemetaan menjadi fungsi yang Anda sediakan.Fakta bahwa tidak ada database yang terlibat tidak berarti bahwa Anda tidak perlu beroperasi pada struktur data, yang bagaimanapun, adalah salah satu esensi pemrograman dalam bahasa apa pun. Adapun pertanyaan terakhir Anda, array Anda tidak hanya berisi angka, tetapi juga objek, string, fungsi, dll.
sumber
.map
dapat melakukan semua yang.forEach
dapat dilakukan (termasuk memodifikasi elemen), ini hanya mengembalikan daftar baru yang dibuat dari fungsi iterator..map()
membuat larik baru, dan tidak mengubah aslinya. Anda memang dapat mengubah larik yang sedang dipetakan itu sendiri, tetapi itu setidaknya akan menjadi non-idiomatik, jika tidak masuk akal..forEach()
, meski serupa, menerapkan fungsinya ke setiap elemen, tetapi selalu mengembalikanundefined
. Terlepas dari semua hal di atas, OP juga menanyakan tentang fungsi spesifiknya sendiri yang ditambahkan ke prototipe array; tidak ada ES5 di masa lalu.forEach
tidak dapat Anda lakukanmap
. Anda tidak peduli dengan nilai pengembalian darimap
dan Anda akan memilikiforEach
. Perbedaannya adalah bahwa ini sangat tidak efektif digunakanmap
untuk tugas-tugas di mana Anda tidak ingin membuat larik baru berdasarkan hasil. Jadi untuk itu, Anda gunakanforEach
.for
lingkaran lama yang sederhana . Saya tidak setuju bahwa ada beberapa perbedaan dalam "keefektifan", tetapi saya juga tidak berpikir ada orang yang berpendapat bahwa yang satu memiliki beberapa keajaiban yang entah bagaimana tidak dapat dicapai. Meskipun sebenarnya ada satu hal yangmap
tidak bisa dilakukan: tidak mengembalikan sebuah array. Ada nilai dalam memiliki JS memenuhi harapan dari bahasa lain untuk perilaku favorit fungsional sepertimap
,reduce
,filter
, dll Misalnya, Anda bisa menerapkanreduceRight
menggunakan blok bangunan serupa, tetapi mengapa tidak menggunakanreduceRight
?b.val = b.val**2
di dalam objek yang dikembalikan . Itulah tepatnya hal yang kami katakan itu mungkin tetapi membingungkan dan tidak idiomatis. Biasanya Anda hanya mengembalikan nilai baru, tidak juga menetapkannya ke array asli:a=[{val:1},{val:2},{val:3},{val:4}]; a.map((b)=>{b.val**2}); JSON.stringify(a);
Perbedaan utama antara kedua metode tersebut adalah konseptual dan gaya: Anda gunakan
forEach
ketika Anda ingin melakukan sesuatu pada atau dengan setiap elemen dari sebuah larik (menurut saya, melakukan "dengan" adalah apa yang dimaksud oleh pos yang Anda kutip dengan "efek samping") , sedangkan Anda menggunakanmap
saat Anda ingin menyalin dan mengubah setiap elemen array (tanpa mengubah aslinya).Karena keduanya
map
danforEach
memanggil fungsi pada setiap item dalam larik, dan fungsi itu ditentukan pengguna, hampir tidak ada yang dapat Anda lakukan dengan satu dan tidak dengan yang lain. Mungkin saja, meskipun jelek, untuk digunakanmap
untuk memodifikasi array di tempat dan / atau melakukan sesuatu dengan elemen array:var a = [{ val: 1 }, { val: 2 }, { val: 3 }]; a.map(function(el) { el.val++; // modify element in-place alert(el.val); // do something with each element }); // a now contains [{ val: 2 }, { val: 3 }, { val: 4 }]
tetapi jauh lebih bersih dan lebih jelas tentang niat Anda untuk menggunakan
forEach
:var a = [{ val: 1 }, { val: 2 }, { val: 3 }]; a.forEach(function(el) { el.val++; alert(el.val); });
Terutama jika, seperti yang biasanya terjadi di dunia nyata,
el
adalah variabel berguna yang dapat dibaca manusia:cats.forEach(function(cat) { cat.meow(); // nicer than cats[x].meow() });
Dengan cara yang sama, Anda dapat dengan mudah menggunakan
forEach
untuk membuat array baru:var a = [1,2,3], b = []; a.forEach(function(el) { b.push(el+1); }); // b is now [2,3,4], a is unchanged
tapi lebih bersih untuk digunakan
map
:var a = [1,2,3], b = a.map(function(el) { return el+1; });
Perhatikan juga bahwa, karena
map
membuat array baru, kemungkinan akan menimbulkan setidaknya beberapa kinerja / memori yang terpukul ketika yang Anda butuhkan hanyalah iterasi, terutama untuk array besar - lihat http://jsperf.com/map-foreachAdapun mengapa Anda ingin menggunakan fungsi-fungsi ini, mereka sangat membantu setiap kali Anda perlu melakukan manipulasi array dalam javascript, yang (bahkan jika kita hanya berbicara tentang javascript di lingkungan browser) cukup sering, hampir setiap saat Anda mengakses larik yang tidak Anda tulis dengan tangan di kode Anda. Anda mungkin berurusan dengan larik elemen DOM di laman, atau data yang ditarik dari permintaan AJAX, atau data yang dimasukkan dalam formulir oleh pengguna. Salah satu contoh umum yang saya temui adalah menarik data dari API eksternal, di mana Anda mungkin ingin menggunakan
map
untuk mengubah data ke dalam format yang Anda inginkan dan kemudian menggunakannyaforEach
untuk mengulangi array baru Anda untuk menampilkannya kepada pengguna Anda.sumber
.map()
sepanjang waktu untuk memodifikasi elemen sebaris. Saya mendapat kesan bahwa itu adalah manfaat utama menggunakan.map
over.forEach
.map
dapat memodifikasi elemen, ya, tetapi itu akan membuat larik yang tidak Anda perlukan. Anda juga harus mempertimbangkan bagaimana memilih satu atau yang lain memungkinkan pembaca menebak apakah Anda memiliki efek samping atau tidakJawaban yang dipilih (dari Ken Redler) menyesatkan.
Sebuah efek samping dalam berarti ilmu komputer bahwa properti dari fungsi / metode alter sebuah negara global [wiki] . Dalam arti sempit, ini mungkin juga termasuk membaca dari keadaan global, bukan dari argumen. Dalam program imperatif atau OO, efek samping muncul hampir sepanjang waktu. Dan Anda mungkin memanfaatkannya tanpa menyadarinya.
Perbedaan signifikan antara
forEach
andmap
is yangmap
mengalokasikan memori dan menyimpan nilai yang dikembalikan, sementaraforEach
membuangnya. Lihat spesifikasi emca untuk informasi lebih lanjut.Adapun alasan mengapa orang mengatakan
forEach
digunakan ketika Anda menginginkan efek samping adalah karena nilai pengembalianforEach
selaluundefined
. Jika tidak ada efek samping (tidak mengubah status global), maka fungsinya hanya membuang-buang waktu cpu. Kompilator yang mengoptimalkan akan menghilangkan blok kode ini dan menggantinya dengan nilai akhir (undefined
).Ngomong-ngomong, perlu dicatat bahwa JavaScript tidak memiliki batasan pada efek samping. Anda masih dapat mengubah larik asli di dalamnya
map
.var a = [1,2,3]; //original var b = a.map( function(x,i){a[i] = 2*x; return x+1} ); console.log("modified=%j\nnew array=%j",a,b); // output: // modified=[2,4,6] // new array=[2,3,4]
sumber
Ini adalah pertanyaan yang indah dengan jawaban yang tidak terduga.
Berikut ini berdasarkan deskripsi resmi dari
Array.prototype.map()
.Tidak ada yang
forEach()
bisa dilakukan yangmap()
tidak bisa. Artinya,map()
adalah super-set yang ketat dariforEach()
.Meskipun
map()
biasanya digunakan untuk membuat array baru, ini juga dapat digunakan untuk mengubah array saat ini. Contoh berikut menggambarkan hal ini:var a = [0, 1, 2, 3, 4], mapped = null; mapped = a.map(function (x) { a[x] = x*x*x; return x*x; }); console.log(mapped); // logs [0, 1, 4, 9, 16] As expected, these are squares. console.log(a); // logs [0, 1, 8, 27, 64] These are cubes of the original array!!
Dalam contoh di atas,
a
itu mudah diatur sedemikian rupa sehinggaa[i] === i
untuki < a.length
. Meski begitu, ia mendemonstrasikan kekuatanmap()
, dan khususnya kemampuannya untuk mengubah larik tempat ia dipanggil.Note1:
Deskripsi resmi menyiratkan bahwa
map()
bahkan dapat mengubah panjang array yang dipanggil! Namun, saya tidak dapat melihat alasan (bagus) untuk melakukan ini.Note2:
Meskipun
map()
peta adalah super-setforEach()
,forEach()
masih harus digunakan di mana seseorang menginginkan perubahan array yang diberikan. Ini membuat niat Anda jelas.Semoga ini bisa membantu.
sumber
mapped = a.map(function (x, i, arr) { arr[i] = x * x * x; return x * x; });.
a.forEach(function(x, i, arr) { ...
, yang, sekali lagi, merupakan cara yang lebih tepat secara konseptual ketika Anda bermaksud untuk mengubah setiap item asli sebagai lawan untuk memetakan nilai dari satu larik ke larik lainnyaAnda dapat menggunakannya
map
seolah-olahforEach
.Namun, itu akan melakukan lebih dari yang seharusnya.
scope
bisa menjadi objek sewenang-wenang; itu tidak berartithis
.Adapun apakah ada kegunaan nyata untuk
map
danforEach
, juga untuk menanyakan apakah ada kegunaan nyata untukfor
atauwhile
loop.sumber
scope = scope || this
berarti "jikascope
falsy (tidak ditentukan, null, false, dll) setel lingkupthis
sebagai gantinya dan lanjutkan".Meskipun semua pertanyaan sebelumnya benar, saya pasti akan membuat perbedaan yang berbeda. Penggunaan
map
danforEach
bisa menyiratkan niat.Saya suka menggunakan
map
ketika saya hanya mengubah data yang ada dengan cara tertentu (tetapi ingin memastikan data asli tidak berubah.Saya suka menggunakan
forEach
saat saya memodifikasi koleksi di tempat.Contohnya,
var b = [{ val: 1 }, { val: 2 }, { val: 3 }]; var c = b.map(function(el) { return { val: el.val + 1 }; // modify element in-place }); console.log(b); // [{ val: 1 }, { val: 2 }, { val: 3 }] console.log(c); // [{ val: 3 }, { val: 4 }, { val: 5 }]
Aturan praktis saya adalah memastikan ketika Anda
map
selalu membuat beberapa objek / nilai baru untuk dikembalikan untuk setiap elemen dari daftar sumber dan mengembalikannya daripada hanya melakukan beberapa operasi pada setiap elemen.Kecuali jika Anda benar-benar perlu mengubah daftar yang ada, tidak masuk akal untuk memodifikasinya di tempat, dan lebih cocok dengan gaya pemrograman fungsional / tidak berubah.
sumber
TL; DR jawaban -
map selalu mengembalikan larik lain.
forEach tidak. Terserah Anda untuk memutuskan apa yang dilakukannya. Kembalikan larik jika Anda ingin atau lakukan sesuatu yang lain jika tidak ingin.
Fleksibilitas diinginkan dalam situasi tertentu. Jika bukan karena apa yang Anda hadapi maka gunakan peta.
sumber
Sekali lagi, saya merasa seperti ahli nujum yang menambahkan jawaban atas pertanyaan yang telah diajukan 5 tahun yang lalu (untungnya ada aktivitas yang agak baru-baru ini, jadi saya bukan satu-satunya yang mengganggu orang mati :).
Orang lain telah memposting tentang pertanyaan utama Anda tentang perbedaan antara fungsi. Tapi untuk...
... lucu kamu harus bertanya. Baru hari ini saya menulis sepotong kode yang menetapkan sejumlah nilai dari ekspresi reguler ke beberapa variabel menggunakan peta untuk transformasi. Itu digunakan untuk mengubah struktur berbasis teks yang sangat rumit menjadi data yang dapat divisualisasikan ... tetapi demi kesederhanaan, saya akan menawarkan contoh menggunakan string tanggal, karena itu mungkin lebih akrab bagi semua orang (meskipun, jika masalah saya sebenarnya terkait tanggal , alih-alih peta, saya akan menggunakan objek Tanggal, yang akan melakukan pekerjaannya sendiri dengan sangat baik).
const DATE_REGEXP = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\.(\d{3})Z$/; const TEST_STRING = '2016-01-04T03:20:00.000Z'; var [ iYear, iMonth, iDay, iHour, iMinute, iSecond, iMillisecond ] = DATE_REGEXP // We take our regular expression and... .exec(TEST_STRING) // ...execute it against our string (resulting in an array of matches)... .slice(1) // ...drop the 0th element from those (which is the "full string match")... .map(value => parseInt(value, 10)); // ...and map the rest of the values to integers... // ...which we now have as individual variables at our perusal console.debug('RESULT =>', iYear, iMonth, iDay, iHour, iMinute, iSecond, iMillisecond);
Jadi ... sementara ini hanya sebuah contoh - dan hanya melakukan transformasi yang sangat mendasar untuk data (hanya sebagai contoh) ... melakukan ini tanpa peta akan menjadi tugas yang jauh lebih membosankan.
Memang, ada tertulis dalam versi JavaScript yang saya tidak berpikir terlalu banyak browser mendukung belum (setidaknya sepenuhnya) tapi - kita sudah ada. Jika saya perlu menjalankannya di browser, saya yakin ini akan berjalan dengan baik.
sumber