Saya telah melihat banyak pertanyaan yang menyarankan penggunaan:
for (var i = 0; i < myArray.length; i++){ /* ... */ }
dari pada:
for (var i in myArray){ /* ... */ }
untuk array, karena iterasi yang tidak konsisten ( lihat di sini ).
Namun, saya tidak dapat menemukan apa pun yang tampaknya lebih menyukai loop berorientasi objek:
myArray.forEach(function(item, index){ /* ... */ });
Yang tampaknya jauh lebih intuitif bagi saya.
Untuk proyek saya saat ini, kompatibilitas IE8 adalah penting, dan saya mempertimbangkan untuk menggunakan polyfill Mozilla , namun saya tidak 100% yakin bagaimana ini akan bekerja.
- Apakah ada perbedaan antara standar for loop (contoh pertama di atas) dan implementasi Array.prototype.forEach oleh browser modern?
- Apakah ada perbedaan antara implementasi browser modern dan implementasi Mozilla yang ditautkan di atas (dengan perhatian khusus pada IE8)?
- Performa bukanlah masalah yang utama, hanya konsistensi properti yang diiterasi.
javascript
arrays
for-loop
internet-explorer-8
iterator
Michael Lewis
sumber
sumber
break
keluarforEach
. Tetapi keuntungan besar adalah membuat ruang lingkup baru dengan fungsi tersebut. Dengan polyfill Anda seharusnya tidak mengalami masalah (setidaknya saya belum menemui masalah).holes
manaundefined
seharusnya dan metode rusak lainnya, sepertislice
danhasOwnProperty
wrt ke objek DOM seperti array. Pengujian saya danes5 shim
telah menunjukkan metode shim yang sesuai dengan spesifikasi (tidak diuji shim MDN).for
lingkaran, untuk itulahsome
.Array.find()
untuk keluar dari loop setelah menemukan kecocokan pertama.Jawaban:
Perbedaan paling mendasar antara
for
loop danforEach
metode adalah, dengan metode sebelumnya, Anda mungkinbreak
keluar dari loop. Anda dapat melakukan simulasicontinue
hanya dengan kembali dari fungsi yang diteruskan keforEach
, tetapi tidak ada cara untuk menghentikan perulangan sama sekali.Selain itu, keduanya mencapai fungsi yang sama secara efektif. Perbedaan kecil lainnya melibatkan cakupan indeks (dan semua variabel yang mengandung) di loop for, karena pengangkatan variabel.
// 'i' is scoped to the containing function for (var i = 0; i < arr.length; i++) { ... } // 'i' is scoped to the internal function arr.forEach(function (el, i) { ... });
Namun, menurut saya itu
forEach
jauh lebih ekspresif — ini mewakili niat Anda untuk mengulang melalui setiap elemen array, dan ini memberi Anda referensi ke elemen, bukan hanya indeks. Secara keseluruhan, sebagian besar tergantung pada selera pribadi, tetapi jika Anda dapat menggunakannyaforEach
, saya akan merekomendasikan untuk menggunakannya.Ada beberapa perbedaan substansial antara kedua versi tersebut, khususnya terkait kinerja. Nyatanya, loop for yang sederhana bekerja jauh lebih baik daripada
forEach
metode, seperti yang ditunjukkan oleh pengujian jsperf ini .Apakah penampilan seperti itu diperlukan bagi Anda atau tidak, terserah Anda untuk memutuskan, dan dalam banyak kasus, saya lebih menyukai ekspresi daripada kecepatan. Perbedaan kecepatan ini kemungkinan besar disebabkan oleh perbedaan semantik kecil antara loop dasar dan metode saat beroperasi pada array renggang, seperti yang dijelaskan dalam jawaban ini .
Jika Anda tidak membutuhkan perilaku
forEach
dan / atau Anda perlu keluar dari loop lebih awal, Anda dapat menggunakan Lo-Dash_.each
sebagai alternatif, yang juga akan bekerja lintas browser. Jika Anda menggunakan jQuery, ini juga menyediakan yang serupa$.each
, cukup perhatikan perbedaan dalam argumen yang diteruskan ke fungsi callback di setiap variasi.(Sedangkan untuk
forEach
polyfill, ini harus bekerja di browser lama tanpa masalah, jika Anda memilih untuk pergi ke rute itu.)sumber
each
tidak berperilaku dengan cara yang sama seperti spesifikasi ECMA5forEach
, mereka cenderung memperlakukan semua larik sebagai padat (untuk menghindari bug IE, asalkan Anda mengetahuinya). Bisa menjadi "gotcha" sebaliknya. Sebagai referensi github.com/es-shims/es5-shim/issues/190Array.prototype.some
yang akan mengulang sampai Anda mengembalikan nilai yang benar atau sampai telah diulang sepenuhnya melalui array.Array.prototype.every
mirip denganArray.prototype.some
tetapi berhenti jika Anda mengembalikan nilai yang salah.Array.prototype.forEach
dengan beberapa versi yang tidak kompatibel akan berpotensi merusak begitu banyak pustaka sehingga menghindarinya karena alasan itu tidak akan membantu.Anda dapat menggunakan fungsi foreach kustom Anda yang akan bekerja jauh lebih baik daripada Array.forEach
Anda harus menambahkan ini sekali ke kode Anda. Ini akan menambah fungsi baru ke Array.
function foreach(fn) { var arr = this; var len = arr.length; for(var i=0; i<len; ++i) { fn(arr[i], i); } } Object.defineProperty(Array.prototype, 'customForEach', { enumerable: false, value: foreach });
Kemudian Anda dapat menggunakannya di mana saja seperti Array.forEach
[1,2,3].customForEach(function(val, i){ });
Satu-satunya perbedaan adalah 3 kali lebih cepat. https://jsperf.com/native-arr-foreach-vs-custom-foreach
PEMBARUAN: Di versi Chrome baru, kinerja .forEach () ditingkatkan. Namun, solusi tersebut dapat memberikan kinerja tambahan di browser lain.
sumber
Disarankan oleh banyak pengembang (misalnya Kyle Simpson) untuk digunakan
.forEach
untuk menunjukkan bahwa larik akan memiliki efek samping dan.map
untuk fungsi murni.for
loop cocok sebagai solusi tujuan umum untuk jumlah loop yang diketahui atau kasus lain yang tidak sesuai karena lebih mudah untuk berkomunikasi karena dukungannya yang luas di sebagian besar bahasa pemrograman.misalnya
/* For Loop known number of iterations */ const numberOfSeasons = 4; for (let i = 0; i < numberOfSeasons; i++) { //Do Something } /* Pure transformation */ const arrayToBeUppercased = ['www', 'html', 'js', 'us']; const acronyms = arrayToBeUppercased.map((el) => el.toUpperCase)); /* Impure, side-effects with .forEach */ const acronymsHolder = []; ['www', 'html', 'js', 'us'].forEach((el) => acronymsHolder.push(el.toUpperCase()));
Dari segi konvensi, ini tampaknya yang terbaik, namun komunitas belum benar-benar menyetujui konvensi pada
for in
loop protokol iterasi yang lebih baru . Secara umum, menurut saya, mengikuti konsep KB yang tampaknya terbuka untuk diadopsi oleh komunitas JS merupakan ide yang bagus.sumber