Efisiensi JavaScript: 'untuk' vs 'forEach' [ditutup]

103

Apa standar saat ini pada tahun 2017 di Javascript dengan for () loop vs .forEach.

Saat ini saya sedang mempelajari Colt Steeles "Web Dev Bootcamp" di Udemy dan dia forEachlebih menyukai forajarannya. Namun, saya telah mencari berbagai hal selama latihan sebagai bagian dari pekerjaan kursus dan saya menemukan lebih banyak rekomendasi untuk menggunakan for-loop daripada forEach. Kebanyakan orang tampaknya menyatakan loop for lebih efisien.

Apakah ini sesuatu yang telah berubah sejak kursus ditulis (sekitar tahun 2015) atau benar-benar pro dan kontra masing-masing, yang akan dipelajari dengan lebih banyak pengalaman.

Saran apa pun akan sangat dihargai.

tonyrobbins
sumber
11
Mengapa mengikat diri Anda pada gagasan subjektif seseorang tentang standar tahun 2017? Mengadopsi standar abadi, seperti menulis kode yang bersih dan dapat dipelihara, mengetahui bahwa para insinyur bekerja keras untuk membuat konstruksi yang paling umum digunakan menjadi sangat efisien, dan kemudian mengoptimalkan kinerja ketika Anda memiliki masalah kinerja tertentu
2
Seorang native forsulit dikalahkan untuk kecepatan murni. forEach()memanggil callback untuk setiap iterasi; jadi, itu jelas membawa serta beberapa overhead.
kanon
1
menjadi pengembang yang jarang saya gunakan untuk atau sebelumnya, sebagian besar pekerjaan dilakukan dengan memetakan, memfilter, atau mengurangi metode.
PADA
12
@AT selama Anda bukan salah satu dari orang-orang yang menggunakan mapmurni untuk iterasi dan membuang array baru yang dihasilkannya. Saya tidak tahu berapa banyak orang yang harus saya koreksi tentang pilihan fungsi tertentu di situs ini saja.
kanon
1
@canon setuju, pemilihan loop penting dan kita harus selalu mengingat keluaran dan residu dari metode tersebut saat memilih. Saya percaya untuk keterbacaan polos "untuk loop" harus dihindari.
PADA

Jawaban:

201

untuk

forloop jauh lebih efisien. Ini adalah konstruksi perulangan yang dirancang khusus untuk melakukan iterasi saat suatu kondisi benar , pada saat yang sama menawarkan mekanisme loncatan (umumnya untuk meningkatkan iterator). Contoh:

for (var i=0, n=arr.length; i < n; ++i ) {
   ...
}

Ini tidak berarti bahwa untuk -loop akan selalu lebih efisien, hanya saja mesin dan browser JS telah mengoptimalkannya untuk itu. Selama bertahun-tahun telah ada kompromi mengenai konstruksi perulangan mana yang lebih efisien (untuk, sementara, mengurangi, membalikkan sementara, dll) - browser dan mesin JS yang berbeda memiliki implementasi mereka sendiri yang menawarkan metodologi berbeda untuk menghasilkan hasil yang sama. Karena browser semakin dioptimalkan untuk memenuhi tuntutan kinerja, secara teoritis [].forEachdapat diterapkan sedemikian rupa sehingga lebih cepat atau sebanding dengan a for.

Manfaat:

  • efisien
  • penghentian loop awal (penghargaan breakdan continue)
  • kontrol kondisi ( i<nbisa apa saja dan tidak terikat pada ukuran array)
  • pelingkupan variabel ( var idaun itersedia setelah loop berakhir)

untuk setiap

.forEachadalah metode yang terutama beriterasi di atas array (juga di atas yang dapat dihitung lainnya, seperti Mapdan Setobjek). Mereka lebih baru dan memberikan kode yang secara subyektif lebih mudah dibaca. Contoh:

[].forEach((val, index)=>{
   ...
});

Manfaat:

  • tidak melibatkan pengaturan variabel (mengulangi setiap elemen dari array)
  • functions / arrow-functions lingkup variabel ke blok
    Dalam contoh di atas, valakan menjadi parameter dari fungsi yang baru dibuat. Jadi, variabel apa pun yang dipanggil valsebelum pengulangan, akan menyimpan nilainya setelah pengulangan berakhir.
  • secara subyektif lebih dapat dipelihara karena mungkin lebih mudah untuk mengidentifikasi apa yang sedang dilakukan kode - iterasi dari enumerable; sedangkan for-loop dapat digunakan untuk sejumlah skema perulangan

Performa

Kinerja adalah topik yang rumit, yang umumnya membutuhkan pengalaman dalam hal pemikiran atau pendekatan sebelumnya. Untuk menentukan sebelumnya (sambil mengembangkan) berapa banyak pengoptimalan yang mungkin diperlukan, seorang programmer harus memiliki gagasan yang baik tentang pengalaman masa lalu dengan kasus masalah, serta pemahaman yang baik tentang solusi potensial.

Menggunakan jQuery dalam beberapa kasus terkadang terlalu lambat (pengembang berpengalaman mungkin tahu itu), sedangkan di lain waktu mungkin bukan masalah, dalam hal ini kepatuhan lintas browser perpustakaan dan kemudahan melakukan fungsi lain (misalnya, AJAX, penanganan acara) akan sepadan dengan waktu pengembangan (dan pemeliharaan) yang dihemat.

Contoh lainnya adalah, jika kinerja dan optimasi adalah segalanya, tidak akan ada kode lain selain mesin atau perakitan. Jelas bukan itu masalahnya karena ada banyak bahasa tingkat tinggi dan rendah yang berbeda, masing-masing dengan pengorbanannya sendiri. Pengorbanan ini termasuk, tetapi tidak terbatas pada spesialisasi, kemudahan dan kecepatan pengembangan, kemudahan dan kecepatan pemeliharaan, kode yang dioptimalkan, kode bebas kesalahan, dll.

Pendekatan

Jika Anda tidak memiliki pemahaman yang baik jika sesuatu memerlukan kode yang dioptimalkan, umumnya merupakan aturan praktis yang baik untuk menulis kode yang dapat dipelihara terlebih dahulu. Dari sana, Anda dapat menguji dan menentukan apa yang perlu lebih diperhatikan saat diperlukan.

Meskipun demikian, pengoptimalan tertentu yang jelas harus menjadi bagian dari praktik umum dan tidak memerlukan pemikiran apa pun. Misalnya, pertimbangkan loop berikut:

for (var i=0; i < arr.length; ++i ){}

Untuk setiap iterasi loop, JavaScript mengambil arr.length, operasi biaya pencarian kunci pada setiap siklus. Tidak ada alasan mengapa ini tidak seharusnya:

for (var i=0, n=arr.length; i < n; ++i){}

Ini melakukan hal yang sama, tetapi hanya mengambil arr.lengthsatu kali, menyimpan variabel dan mengoptimalkan kode Anda.

vol7ron
sumber
25
Jawaban yang sangat baik, menyeluruh, tidak sombong, tidak terikat pada satu titik waktu, implementasi, atau uji tolok ukur mikro.
1
Sempurna, itulah yang saya cari dan memberikan kedalaman lebih dari yang bisa video. Saya sangat menghargai ini, menjadi baru ada begitu banyak yang harus dipelajari dan ini adalah hal-hal yang mudah dilewati dengan hanya menyukai satu sama lain tanpa alasan yang dapat menghalangi Anda di masa depan. Terimakasih banyak!
tonyrobbins
2
for-loop sering kali memiliki keuntungan dalam hal debugging: mereka trivila untuk masuk, breakpoint dan inspeksi. Dengan forEach (), level callback tambahan bisa sedikit memperumit masalah.
Eric Grange
1
@FelipeBuccioni terima kasih, saya benar-benar akan memeriksanya karena saya pikir mesin sekarang memeriksa apakah sebuah array akan dimutasi untuk menentukan apakah panjangnya di-cache. Padahal, untuk tujuan lama saya pikir mesin pengoptimalan tidak begitu murah hati dan panjangnya adalah kinerja yang sukses pada setiap iterasi. Saya akan melihat artikel Anda dan memasukkannya ke dalam jawaban ketika saya punya waktu, atau mudah-mudahan anggota komunitas yang luar biasa akan membuat perubahan sebagai suntingan untuk saya :)
vol7ron
6
Saya sangat menikmati penjelasan dalam jawaban dan frasa ini [...], if performance and optimization was everything, there would be no other code than machine or assembly.. Saya percaya bahwa dengan letpernyataan untuk mendeklarasikan variabel lokal lingkup blok, manfaat kedua forEachtidak lagi merupakan keuntungan atas forpengulangan kecuali dalam lingkungan tanpa dukungan untuk let.
pengguna7393973