Bagaimana saya bisa loop melalui semua entri dalam array menggunakan JavaScript?
Saya pikir itu adalah sesuatu seperti ini:
forEach(instance in theArray)
Di mana ukuranarray
adalah array saya, tapi ini tampaknya tidak benar.
TL;DR
bagi-in
, kecuali jika anda menggunakannya dengan pengamanan atau setidaknya menyadari mengapa hal itu mungkin menggigit anda. bagi-dari
lingkaran (ES2015+ saja), Array#forEach
(spec
| MDN
) (atau kerabat beberapa
dan semacamnya) (ES5+ saja), untuk
loop, -in
dengan pengamanan.
Tapi ada's banyak lebih banyak untuk mengeksplorasi, membaca... JavaScript memiliki kuat semantik untuk perulangan melalui array dan array seperti benda-benda. I've membagi jawaban ke dalam dua bagian: Pilihan untuk asli array, dan pilihan untuk hal-hal yang hanya array-suka, seperti argumen
objek, lain iterable benda (ES2015+), DOM koleksi, dan sebagainya.
I'll cepat perhatikan bahwa anda dapat menggunakan ES2015 pilihan sekarang, bahkan pada ES5 mesin, oleh transpiling ES2015 untuk ES5. Pencarian "ES2015 transpiling" / "ES6 transpiling" untuk lebih...
Oke, let's melihat pilihan kami:
Anda memiliki tiga pilihan di ECMAScript 5 ("ES5"), versi yang paling luas didukung pada saat ini, dan menambahkan dua lagi di ECMAScript 2015 ("ES2015", "ES6"):
forEach
dan yang terkait (ES5+) untuk
loop bagi-in
benar bagi-dari
(menggunakan iterator secara implisit) (ES2015+) forEach
dan terkaitDalam samar-samar-lingkungan modern (jadi, tidak IE8) di mana anda memiliki akses ke Array
fitur yang ditambahkan oleh ES5 (secara langsung atau menggunakan polyfills), anda dapat menggunakan forEach
(spec
| MDN
):
var a = ["a", "b", "c"];
a.forEach(function(entry) {
console.log(entry);
});
forEach
menerima sebuah fungsi callback dan, opsional, nilai untuk digunakan sebagai ini
ketika menyebut bahwa callback (tidak digunakan di atas). Callback ini disebut untuk setiap entri dalam array, dalam rangka, melompat-lompat tidak ada entri dalam array jarang. Meskipun saya hanya menggunakan satu argumen di atas, callback adalah yang disebut dengan tiga: nilai dari masing-masing entri, indeks yang masuk, dan referensi ke array anda're iterasi (dalam kasus anda fungsi doesn't sudah memiliki itu berguna).
Kecuali anda're mendukung browser usang seperti IE8 (yang NetApps menunjukkan pada lebih dari 4% market share tulisan ini di bulan September 2016), anda dapat dengan senang hati menggunakan forEach
di umum-tujuan halaman web tanpa shim. Jika anda perlu dukungan browser usang, shimming/polyfilling forEach
ini mudah dilakukan (cari "es5 shim" untuk beberapa pilihan).
forEach
memiliki manfaat bahwa anda don't harus menyatakan pengindeksan dan nilai variabel yang berisi ruang lingkup, karena mereka're disediakan sebagai argumen untuk iterasi fungsi, dan begitu baik scoped hanya itu iterasi.
Jika anda're khawatir tentang runtime biaya pembuatan fungsi panggilan untuk masing-masing hotel yang masuk, don't; detail.
Selain itu, forEach
adalah "loop melalui mereka semua" fungsi, tapi ES5 didefinisikan beberapa lainnya berguna "bekerja dengan cara anda melalui array dan melakukan hal-hal" fungsi, termasuk:
setiap
(berhenti perulangan pertama kalinya callback kembali palsu
atau sesuatu falsey) c
(berhenti perulangan pertama kalinya callback mengembalikan true
atau sesuatu truthy) filter
(menciptakan sebuah array baru yang termasuk unsur-unsur mana fungsi filter kembali benar
dan menghilangkan orang-orang di mana ia kembali false
) peta
(menciptakan sebuah array baru dari nilai yang dikembalikan oleh callback) mengurangi
(membangun nilai dengan berulang kali menelepon balik, lewat di nilai sebelumnya; lihat spec untuk rincian; berguna untuk menjumlahkan isi sebuah array dan banyak hal lain)reduceRight
(seperti mengurangi
, tetapi bekerja di turun daripada urutan menaik) untuk
loopKadang-kadang cara lama adalah yang terbaik:
var index;
var a = ["a", "b", "c"];
for (index = 0; index < a.length; ++index) {
console.log(a[index]);
}
Jika panjang array won't berubah selama loop, dan's dalam kinerja-sensitif kode (mungkin), yang sedikit lebih rumit versi meraih suhu udara menghangat hingga depan mungkin seorang kecil lebih cepat:
var index, len;
var a = ["a", "b", "c"];
for (index = 0, len = a.length; index < len; ++index) {
console.log(a[index]);
}
Dan/atau menghitung mundur:
var index;
var a = ["a", "b", "c"];
for (index = a.length - 1; index >= 0; --index) {
console.log(a[index]);
}
Tapi dengan modern JavaScript engine, it's langka yang anda butuhkan untuk menambah bahwa bit terakhir dari jus.
Di ES2015 dan lebih tinggi, anda dapat membuat indeks dan nilai variabel lokal untuk untuk
loop:
let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
let value = a[index];
console.log(index, value);
}
//console.log(index); // would cause "ReferenceError: index is not defined"
//console.log(value); // would cause "ReferenceError: value is not defined"
let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
let value = a[index];
console.log(index, value);
}
try {
console.log(index);
} catch (e) {
console.error(e); // "ReferenceError: index is not defined"
}
try {
console.log(value);
} catch (e) {
console.error(e); // "ReferenceError: value is not defined"
}
Dan ketika anda melakukan itu, bukan hanya nilai
tapi juga index
yang diciptakan untuk masing-masing loop iterasi, yang berarti penutupan dibuat dalam lingkaran tubuh menyimpan referensi ke index
(dan nilai
) dibuat untuk spesifik iterasi:
let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
divs[index].addEventListener('click', e => {
console.log("Index is: " + index);
});
}
let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
divs[index].addEventListener('click', e => {
console.log("Index is: " + index);
});
}
<div>zero</div>
<div>one</div>
<div>two</div>
<div>three</div>
<div>four</div>
Jika anda memiliki lima divs, anda'd mendapatkan "Index: 0" jika anda diklik pertama dan "Index: 4" jika anda mengklik terakhir. Ini tidak tidak bekerja jika anda menggunakan var
bukan kita
.
bagi-in
benarAnda'll mendapatkan orang-orang memberitahu anda untuk menggunakan bagi-in
, tetapi itu's tidak apa bagi-in
adalah untuk. bagi-in
loop melalui enumerable sifat dari sebuah objek, tidak indeks dari array. Pesanan tidak dijamin, bahkan di ES2015 (ES6). ES2015+ mendefinisikan perintah untuk objek properti (via [[OwnPropertyKeys]]
, [[Enumerate]]
, dan hal-hal yang menggunakannya seperti Objek.getOwnPropertyKeys
), tapi itu tidak mendefinisikan bahwa bagi-in
akan mengikuti urutan yang. (Rincian dalam jawaban.)
Satu-satunya kasus penggunaan untuk bagi-in
pada array adalah:
bagi-in
untuk mengunjungi orang-orang sparese elemen array jika anda menggunakan perlindungan yang sesuai:
// `a` is a sparse array
var key;
var a = [];
a[0] = "a";
a[10] = "b";
a[10000] = "c";
for (key in a) {
if (a.hasOwnProperty(key) && // These checks are
/^0$|^[1-9]\d*$/.test(key) && // explained
key <= 4294967294 // below
) {
console.log(a[key]);
}
}
Perhatikan tiga cek:
panjang
dapat memiliki. (E. g., array's panjang cocok di 32-bit unsigned integer.) (Alat peraga untuk RobG untuk menunjukkan di komentar pada posting blog saya bahwa saya tes sebelumnya tidak't benar.)
Anda tidak't melakukan itu di kode inline, tentu saja. Anda'd menulis sebuah fungsi utilitas. Mungkin:
// Utility function for antiquated environments without `forEach`
var hasOwn = Object.prototype.hasOwnProperty;
var rexNum = /^0$|^[1-9]\d*$/;
function sparseEach(array, callback, thisArg) {
var index;
for (var key in array) {
index = +key;
if (hasOwn.call(a, key) &&
rexNum.test(key) &&
index <= 4294967294
) {
callback.call(thisArg, array[key], index, array);
}
}
}
var a = [];
a[5] = "five";
a[10] = "ten";
a[100000] = "one hundred thousand";
a.b = "bee";
sparseEach(a, function(value, index) {
console.log("Value at " + index + " is " + value);
});
bagi-dari
(menggunakan iterator secara implisit) (ES2015+)ES2015 menambahkan iterator untuk JavaScript. Cara termudah untuk menggunakan iterator adalah baru bagi-dari
pernyataan. Ini terlihat seperti ini:
const a = ["a", "b", "c"];
for (const val of a) {
console.log(val);
}
Di bawah selimut, yang mendapat iterator dari array dan loop melalui itu, untuk mendapatkan nilai dari itu. Ini doesn't memiliki masalah yang menggunakan bagi-in
, karena menggunakan iterator yang didefinisikan oleh objek (array), dan array menentukan bahwa mereka iterator iterate melalui mereka entri (bukan sifat mereka). Tidak seperti bagi-di
di ES5, urutan di mana entri yang dikunjungi adalah urutan numerik dari indeks mereka.
Kadang-kadang, anda mungkin ingin menggunakan sebuah iterator tegas. Anda bisa melakukan itu juga, meskipun itu's banyak clunkier dari bagi-dari
. Ini terlihat seperti ini:
const a = ["a", "b", "c"];
const it = a.values();
let entry;
while (!(entry = it.next()).done) {
console.log(entry.value);
}
Iterator adalah suatu objek yang cocok dengan Iterator definisi dalam spesifikasi. Yang next
kembali metode baru hasil objek setiap kali anda menyebutnya. Hasilnya objek memiliki properti, selesai
, memberitahu kita apakah itu's dilakukan, dan properti nilai
dengan nilai iterasi itu. (selesai
adalah opsional jika itu akan menjadi false
, nilai
adalah opsional jika itu akan menjadi undefined
.)
Arti dari nilai
bervariasi tergantung pada iterator; array dukungan (setidaknya) tiga fungsi yang kembali iterator:
: Ini adalah salah satu yang saya gunakan di atas. Ini mengembalikan sebuah iterator di mana masing-masing
nilaiadalah array yang masuk untuk iterasi (
"a",
"b", dan
"c"` pada contoh sebelumnya). tombol()
: Mengembalikan sebuah iterator di mana masing-masing nilai
adalah kunci untuk iterasi (jadi untuk kita a
di atas, yang akan menjadi "0"
, kemudian "1"
, kemudian "2"
). entri()
: Mengembalikan sebuah iterator di mana masing-masing nilai
adalah array dalam bentuk [key, value]
untuk iterasi. Terlepas dari benar array, ada juga array-suka benda-benda yang memiliki panjang
properti dan sifat numerik dengan nama: NodeList
kasus, argumen
objek, dll. Bagaimana kita loop melalui isinya?
Setidaknya beberapa, dan mungkin sebagian besar atau bahkan semua, dari berbagai pendekatan di atas sering berlaku juga untuk hotel-benda seperti:
Gunakan forEach
dan yang terkait (ES5+)
Berbagai fungsi pada Array.prototipe
adalah "sengaja generik" dan biasanya dapat digunakan pada array-benda seperti melalui Fungsi#panggilan
atau Fungsi#menerapkan
. (Lihat Peringatan untuk host yang disediakan benda-benda pada akhir jawaban ini, tapi itu's masalah yang langka.)
Misalkan anda ingin menggunakan forEach
pada Node
's childNodes
properti. Anda'd lakukan ini:
Array.prototipe.forEach.panggilan(node.childNodes, fungsi(anak) {
// Lakukan sesuatu dengan anak
});
Jika anda're akan lakukan yang banyak, anda mungkin ingin untuk ambil salinan fungsi referensi ke sebuah variabel untuk digunakan kembali, misalnya:
// (Ini adalah semua yang mungkin dalam beberapa ruang lingkup fungsi)
var forEach = Array.prototipe.forEach;
// Kemudian...
forEach.panggilan(node.childNodes, fungsi(anak) {
// Lakukan sesuatu dengan anak
});
Menggunakan sederhana untuk
loop
Jelas, sederhana untuk
loop berlaku untuk array seperti benda-benda.
Gunakan bagi-in
benar
bagi-in
dengan perlindungan yang sama dengan array harus bekerja dengan array-benda seperti juga; peringatan untuk host yang disediakan benda-benda di #1 di atas mungkin berlaku.
Gunakan bagi-dari
(menggunakan iterator secara implisit) (ES2015+)
bagi-dari
akan menggunakan iterator yang disediakan oleh objek (jika ada); kita'll harus melihat bagaimana hal ini memainkan dengan berbagai fasilitas seperti benda-benda, terutama tuan rumah yang diberikan orang-orang. Misalnya, spesifikasi untuk NodeList
dari querySelectorAll
telah diperbarui untuk mendukung iterasi. Spec untuk HTMLCollection
dari getElementsByTagName
tidak.
Menggunakan iterator secara eksplisit (ES2015+) Lihat #4, we'll harus melihat bagaimana iterator bermain keluar.
Lain kali, anda mungkin ingin mengkonversi array objek seperti menjadi sebuah array. Melakukan hal itu adalah mengherankan mudah:
Gunakan iris
metode array
Kita dapat menggunakan iris
metode array, yang seperti metode lain yang disebutkan di atas adalah "sengaja generik" dan agar dapat digunakan dengan berbagai benda seperti, seperti ini:
var trueArray = Array.prototipe.slice.panggilan(arrayLikeObject);
Jadi misalnya, jika kita ingin mengkonversi NodeList
menjadi sebuah array, kita bisa melakukan hal ini:
var div = Array.prototipe.slice.panggilan(dokumen.querySelectorAll("div"));
Melihat Peringatan untuk host yang disediakan benda-benda di bawah ini. Secara khusus, perhatikan bahwa hal ini akan gagal di IE8 dan sebelumnya, yang don't membiarkan anda menggunakan host-menyediakan benda-benda seperti ini
seperti itu.
Gunakan menyebar sintaks (...
)
It's juga memungkinkan untuk menggunakan ES2015's menyebar sintaks dengan mesin JavaScript yang mendukung fitur ini:
var trueArray = [...iterableObject];
Jadi misalnya, jika kita ingin mengkonversi NodeList
menjadi sebuah array, dengan menyebar sintaks ini menjadi cukup singkat:
var div = [...dokumen.querySelectorAll("div")];
Gunakan Array.dari
(spec) | (MDN)
Array.dari
(ES2015+, tapi mudah polyfilled) menciptakan sebuah array dari array objek seperti, opsional lewat entri melalui pemetaan fungsi pertama. Jadi:
var div = Array.dari(dokumen.querySelectorAll("div"));
Atau jika anda ingin mendapatkan sebuah array dari tag nama-nama dari unsur-unsur dengan kelas yang diberikan, anda'd gunakan pemetaan fungsi:
// Panah fungsi (ES2015):
var div = Array.dari(dokumen.querySelectorAll(".beberapa kelas"), elemen => elemen.tagName);
// Fungsi standar (sejak Array.dari
dapat shimmed):
var div = Array.dari(dokumen.querySelectorAll(".beberapa kelas"), fungsi(elemen) {
kembali elemen.tagName;
});
Jika anda menggunakan Array.prototipe fungsi dengan *host-disediakan* array-benda seperti (DOM daftar dan hal-hal lain yang disediakan oleh browser daripada mesin JavaScript), anda perlu pastikan untuk menguji target anda lingkungan untuk memastikan tuan rumah yang disediakan objek yang berperilaku baik. **Paling tidak berperilaku dengan benar** (sekarang), tapi itu's penting untuk menguji. Alasannya adalah bahwa sebagian besar dari
Array.prototipemetode anda're cenderung ingin menggunakan bergantung pada host-objek yang disediakan memberikan jawaban yang jujur abstrak [
[[HasProperty]]`]19 operasi. Seperti tulisan ini, browser melakukan pekerjaan yang sangat baik dari ini, tapi 5.1 spec tidak memungkinkan untuk kemungkinan host-objek yang disediakan mungkin tidak jujur. It's di §8.6.2, beberapa paragraf di bawah meja besar di bagian awal dari bagian tersebut), di mana dikatakan:
Host benda yang dapat menerapkan ini metode internal dengan cara apapun kecuali ditentukan lain; misalnya, salah satu kemungkinan adalah bahwa
[[Mendapatkan]]
dan[[Masukan]]
untuk host tertentu objek memang mengambil dan menyimpan nilai properti tapi[[HasProperty]]
selalu menghasilkan palsu. (Saya tidak't menemukan setara dengan bertele-tele di ES2015 spec, tapi itu's pasti masih akan terjadi.) Sekali lagi, tulisan ini umum host-disediakan fasilitas-benda seperti di browser modern [NodeList
contoh, misalnya] jangan menangani[[HasProperty]]
dengan benar, tetapi itu's penting untuk menguji.)
Catatan: Ini jawabannya adalah putus asa out-of-date. Untuk pendekatan yang lebih modern, lihat metode yang tersedia pada array. Metode bunga mungkin:
Cara standar untuk iterate array di JavaScript adalah vanili untuk
loop:
var length = arr.length,
element = null;
for (var i = 0; i < length; i++) {
element = arr[i];
// Do something with element
}
Catatan, bagaimanapun, bahwa pendekatan ini hanya baik jika anda memiliki sebuah array padat, dan indeks masing-masing ditempati oleh sebuah elemen. Jika array jarang, maka anda dapat menjalankan ke dalam masalah kinerja dengan pendekatan ini, karena anda akan iterate atas banyak indeks yang tidak benar-benar yang ada dalam array. Dalam hal ini, for .. in
-loop mungkin ide yang lebih baik. Namun**, anda harus menggunakan pengamanan yang memadai untuk memastikan bahwa hanya sifat-sifat yang diinginkan dari array (yaitu, elemen array) yang ditindaklanjuti, karena for..in
-loop juga akan disebutkan di browser lama, atau jika sifat tambahan yang didefinisikan sebagai enumerable
.
Di ECMAScript 5 akan ada forEach metode pada array prototipe, tetapi hal ini tidak didukung di browser lama. Sehingga untuk dapat menggunakannya secara konsisten anda harus memiliki lingkungan yang mendukung (misalnya, Node.js untuk server side JavaScript), atau gunakan "Polyfill". Yang Polyfill untuk fungsi ini, namun, sepele dan sejak itu membuat kode lebih mudah dibaca, lebih baik polyfill untuk memasukkan.
Jika anda menggunakan jQuery perpustakaan, anda dapat menggunakan jQuery.masing-masing:
$.each(yourArray, function(index, value) {
// do your stuff here
});
EDIT :
Sesuai pertanyaan, pengguna ingin kode di javascript bukan jquery sehingga edit
var length = yourArray.length;
for (var i = 0; i < length; i++) {
// Do something with yourArray[i].
}
Saya pikir terbalik untuk loop layak disebutkan di sini:
for (var i = array.length; i--; ) {
// process array[i]
}
len
variabel, atau membandingkan terhadap array.panjang
pada setiap iterasi, salah satu yang mungkin menjadi langkah optimasi. forEach()
dan untuk ES6's untuk ... dari
. Beberapa pengusaha menggunakan reverse for loop secara default, kecuali jika ada alasan yang baik untuk loop ke depan. Meskipun keuntungan kinerja yang biasanya tidak signifikan, hal semacam jeritan:
"Hanya melakukan ini untuk setiap item dalam daftar, I don't peduli tentang perintah!" Namun dalam praktek yang tidak ** benar-benar dapat diandalkan indikasi kesengajaan, karena tidak bisa dibedakan dari orang-orang kesempatan ketika anda **do peduli tentang ketertiban, dan benar-benar butuh ** loop secara terbalik. Sehingga dalam kenyataan lain yang membangun akan diperlukan untuk secara akurat mengungkapkan "don't peduli" maksud, sesuatu yang saat ini tidak tersedia dalam banyak bahasa, termasuk ECMAScript, tapi yang bisa disebut, misalnya,
forEachUnordered()
. Jika order doesn't peduli, dan efisiensi adalah kekhawatiran (dalam loop terdalam dari sebuah permainan atau animasi engine), maka hal ini mungkin dapat diterima untuk menggunakan reverse for loop sebagai anda pergi-untuk pola. Hanya ingat bahwa melihat terbalik untuk loop dalam kode yang ada tidak selalu berarti bahwa perintah tersebut tidak relevan!Ini adalah lebih baik untuk menggunakan forEach()
Secara umum untuk tingkat yang lebih tinggi kode mana kejelasan dan keselamatan ini adalah masalah yang lebih besar, saya sebelumnya dianjurkan menggunakan
Array::forEach
sebagai default pola perulangan (meskipun hari-hari ini saya memilih untuk menggunakanuntuk..dari
). Alasan untuk lebih memilihforEach
selama reverse loop adalah:
untuk
dan sementara
loop). Ada perdebatan tentang apakah untuk..
atau forEach()
yang lebih baik:
untuk..dari
membutuhkan polyfill untuk iterator, membuat aplikasi anda sedikit lebih lambat untuk mengeksekusi dan sedikit lebih besar untuk men-download. peta
dan filter
), beberapa front-end gaya panduan ban untuk..dari
benar-benar! untuk..dari
sekarang didukung.menunggu
tidak bekerja dalam forEach()
. Menggunakan untuk..dari
adalah jelas pola dalam kasus ini.
Secara pribadi, saya cenderung untuk menggunakan apa pun yang terlihat paling mudah untuk dibaca, kecuali kinerja atau minification telah menjadi perhatian utama. Jadi hari ini saya lebih suka menggunakan untuk..dari
bukan forEach()
, tapi aku akan selalu menggunakan peta
atau filter
atau cari
atau c
ketika berlaku.
(Demi rekan-rekan saya, saya jarang menggunakan reduce
.) for (var i = 0; i < array.length; i++) { ... } // Forwards
for (var i = array.length; i--; ) { ... } // Reverse
Anda akan melihat bahwa aku--
ini tengah klausa (di mana biasanya kita lihat perbandingan) dan kalimat terakhir adalah kosong (di mana kita biasanya melihat i++
). Itu berarti bahwa aku--
juga digunakan sebagai kondisi untuk kelanjutan. Yang terpenting, hal ini dilaksanakan dan diperiksa sebelum setiap iterasi.
array.panjang
tanpa meledak?
Karena aku--
berjalan sebelum setiap iterasi, pada iterasi pertama kami benar-benar akan mengakses item di array.panjang - 1
yang menghindari masalah dengan <menyerang>Array-out-of-batas</strike> undefined
barang-barang. aku--
mengevaluasi ke falsey nilai (ketika itu menghasilkan 0).
Kuncinya adalah bahwa tidak seperti - i
, akhiran aku--
operator decrements aku
tapi hasil nilai sebelum decrement. Konsol anda dapat menunjukkan hal ini:
> var i = 5; [aku, aku..., aku];
[5, 5, 4]
Sehingga pada akhir iterasi, i sebelumnya 1 dan aku--
perubahan ekspresi itu untuk 0 tapi benar-benar hasil 1 (truthy), dan kondisi berlalu. Pada iterasi berikutnya aku--
perubahan saya untuk -1 tapi hasil 0 (falsey), menyebabkan eksekusi untuk segera keluar dari bagian bawah loop.
Dalam tradisional ke depan untuk loop, i
dan ++i
yang dapat diganti-ganti (seperti Douglas Crockford poin). Namun di reverse for loop, karena kami pengurangan juga kondisi kita berekspresi, kita harus tetap dengan aku--
jika kita ingin memproses item pada indeks 0. Beberapa orang suka untuk menggambar panah kecil di balik untuk
loop, dan berakhir dengan wink:
for (var i = array.length; i --> 0 ;) {
Kredit pergi ke WYL untuk menunjukkan manfaat dan kengerian reverse for loop.
Beberapa C gaya bahasa yang menggunakan foreach
untuk loop melalui mantri. Dalam JavaScript ini dilakukan dengan for..in
struktur loop:
var index,
value;
for (index in obj) {
value = obj[index];
}
Ada yang menangkap. for..in
akan loop melalui masing-masing objek's enumerable anggota, dan anggota pada prototipe. Untuk menghindari membaca nilai-nilai yang diwariskan melalui objek's prototipe, hanya memeriksa jika properti milik objek:
for (i in obj) {
if (obj.hasOwnProperty(i)) {
//do stuff
}
}
Selain itu, ECMAScript 5 telah ditambahkan forEach
metode untuk Array.prototipe
yang dapat digunakan untuk menghitung lebih dari array menggunakan calback (yang polyfill dalam dokumen sehingga anda masih dapat menggunakannya untuk browser lama):
arr.forEach(function (val, index, theArray) {
//do stuff
});
It's penting untuk dicatat bahwa Array.prototipe.forEach
doesn't istirahat ketika callback kembali palsu
. jQuery dan Underscore.js memberikan variasi mereka sendiri pada masing-masing
untuk memberikan loop yang bisa hubung pendek.
Jika anda ingin loop melalui array, menggunakan standar tiga bagian untuk
loop.
for (var i = 0; i < myArray.length; i++) {
var arrayItem = myArray[i];
}
Anda bisa mendapatkan kinerja beberapa optimisations dengan caching myArray.panjang
atau iterasi ke belakang.
Saya tahu ini adalah sebuah posting lama, dan ada begitu banyak jawaban yang besar sudah. Untuk sedikit lebih kelengkapan saya pikir saya'd melempar satu sama lain dengan menggunakan AngularJS. Tentu saja, ini hanya berlaku jika anda're menggunakan Sudut, jelas, meskipun demikian saya'd ingin menempatkan itu pula.
sudut.forEach
membutuhkan 2 argumen dan opsional ketiga argumen. Argumen pertama adalah objek (array) untuk iterate atas, argumen kedua adalah iterator fungsi, dan opsional argumen ketiga adalah objek konteks (pada dasarnya sebagaimana dimaksud dalam loop sebagai 'ini'.
Ada berbagai cara untuk menggunakan forEach loop dari sudut. Yang paling sederhana dan mungkin yang paling sering digunakan adalah
var temp = [1, 2, 3];
angular.forEach(temp, function(item) {
//item will be each element in the array
//do something
});
Cara lain yang berguna untuk menyalin item dari satu array ke yang lain
var temp = [1, 2, 3];
var temp2 = [];
angular.forEach(temp, function(item) {
this.push(item); //"this" refers to the array passed into the optional third parameter so, in this case, temp2.
}, temp2);
Meskipun, anda don't harus melakukan itu, anda hanya dapat melakukan berikut ini dan itu's setara dengan contoh sebelumnya:
angular.forEach(temp, function(item) {
temp2.push(item);
});
Sekarang ada pro dan kontra dari menggunakan sudut.forEach
fungsi sebagai lawan untuk dibangun di vanilla-rasa untuk
loop.
Pro
sudut.forEach
akan menggunakan ES5 loop forEach. Sekarang, saya akan mendapatkan efisiensi dalam kontra bagian, seperti forEach loop banyak lebih lambat daripada for loop. Saya menyebutkan hal ini sebagai pro karena itu's bagus untuk menjadi konsisten dan standar.Pertimbangkan hal berikut 2 nested loop, yang melakukan hal yang sama. Let's mengatakan bahwa kita memiliki 2 array dari objek dan setiap objek berisi array dari hasil, yang masing-masing memiliki Nilai properti yang's a string (atau apa pun). Dan let's mengatakan kita perlu untuk iterate atas setiap hasil, dan jika mereka're sama kemudian melakukan beberapa tindakan:
angular.forEach(obj1.results, function(result1) {
angular.forEach(obj2.results, function(result2) {
if (result1.Value === result2.Value) {
//do something
}
});
});
//exact same with a for loop
for (var i = 0; i < obj1.results.length; i++) {
for (var j = 0; j < obj2.results.length; j++) {
if (obj1.results[i].Value === obj2.results[j].Value) {
//do something
}
}
}
Memang ini adalah sangat sederhana contoh hipotetis, tapi aku've tertulis triple tertanam untuk loop menggunakan pendekatan kedua dan itu sangat sulit untuk membaca, dan menulis untuk hal itu.
Karena ...
sudut.forEach
, dan pribumi forEach
, dalam hal ini, keduanya banyak lebih lambat dari normal untuk
loop....tentang 90% lebih lambat. Jadi untuk set data yang besar, yang terbaik untuk tetap pada asli untuk
loop.lanjutkan
adalah benar-benar didukung oleh "kecelakaan", terus di sudut.forEach
anda sederhana menempatkan kembali;
pernyataan dalam fungsi seperti sudut.forEach(array, function(item) { if (someConditionIsTrue) return; });
yang akan menyebabkan itu untuk terus keluar dari fungsi untuk iterasi. Ini juga karena fakta bahwa penduduk asli forEach
tidak mendukung istirahat atau melanjutkan baik.I'm yakin ada's berbagai pro dan kontra juga, dan jangan ragu untuk menambahkan apapun yang anda lihat cocok. Saya merasa bahwa, garis bawah, jika anda membutuhkan efisiensi, tetap dengan hanya asli untuk
loop untuk perulangan kebutuhan. Tapi, jika anda dataset yang lebih kecil dan beberapa efisiensi yang lebih baik untuk menyerah dalam pertukaran untuk dibaca dan writability, maka dengan segala cara membuang sudut.forEach
itu bad boy.
A forEach pelaksanaan ([lihat di jsFiddle][1]):
function forEach(list,callback) {
var length = list.length;
for (var n = 0; n < length; n++) {
callback.call(list[n]);
}
}
var myArray = ['hello','world'];
forEach(
myArray,
function(){
alert(this); // do something
}
);
Jika anda don't mengosongkan pikiran array:
var x;
while(x = y.pop()){
alert(x); //do something
}
x
akan berisi nilai terakhir dari y
dan itu akan dihapus dari array. Anda juga dapat menggunakan shift()
yang akan memberikan dan menghapus item pertama dari y
.
Solusi mudah sekarang akan menggunakan underscore.js perpustakaan. It's menyediakan banyak alat yang berguna, seperti masing-masing
dan secara otomatis akan mendelegasikan pekerjaan ke pekerjaan native forEach
jika tersedia.
A CodePen contoh dari cara kerjanya adalah:
var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});
Array.prototipe.forEach()
.untuk masing-masing (variabel dalam object)
sudah ditinggalkan sebagai bagian dari ECMA-357 (EAX) standar.untuk (variabel dari objek)
sebagai bagian dari Harmoni (ECMAScript 6) proposal.Ada tiga implementasi foreach
di jQuery sebagai berikut.
var a = [3,2];
$(a).each(function(){console.log(this.valueOf())}); //Method 1
$.each(a, function(){console.log(this.valueOf())}); //Method 2
$.each($(a), function(){console.log(this.valueOf())}); //Method 3
Seperti ECMAScript 6:
list = [0, 1, 2, 3]
for (let obj of list) {
console.log(obj)
}
Di mana dari
menghindari keanehan yang terkait dengan di
dan membuatnya bekerja seperti untuk
loop dari bahasa lain, dan membiarkan
mengikat aku
dalam loop sebagai lawan di dalam fungsi.
Yang kurawal ({}
) dapat dihilangkan ketika hanya ada satu perintah (misalnya dalam contoh di atas).
Mungkin untuk(i = 0; i < array.length; i++)
loop adalah bukan pilihan terbaik. Mengapa? Jika anda memiliki ini:
var array = new Array();
array[1] = "Hello";
array[7] = "World";
array[11] = "!";
Method ini akan memanggil dari array[0]
untuk array[2]
. Pertama, ini akan referensi pertama variabel yang anda don't bahkan, kedua anda tidak akan memiliki variabel-variabel dalam array, dan ketiga hal ini akan membuat kode yang lebih berani. Lihat di sini, it's apa yang saya gunakan:
for(var i in array){
var el = array[i];
//If you want 'i' to be INT just put parseInt(i)
//Do something with el
}
Dan jika anda ingin menjadi fungsi, anda dapat melakukan ini:
function foreach(array, call){
for(var i in array){
call(array[i]);
}
}
Jika anda ingin istirahat, sedikit lebih logika:
function foreach(array, call){
for(var i in array){
if(call(array[i]) == false){
break;
}
}
}
Contoh:
foreach(array, function(el){
if(el != "!"){
console.log(el);
} else {
console.log(el+"!!");
}
});
Kembali:
//Hello
//World
//!!!
Ada isn't setiap untuk setiap
loop asli JavaScript. Anda dapat menggunakan perpustakaan untuk mendapatkan fungsi ini (saya sarankan Underscore.js), menggunakan sederhana untuk
di lingkaran.
for (var instance in objects) {
...
}
Namun, perhatikan bahwa mungkin ada alasan untuk menggunakan aplikasi yang lebih sederhana untuk
loop (lihat Stack Overflow pertanyaan Mengapa menggunakan "untuk...dalam" dengan array iterasi seperti ide yang buruk?)
var instance;
for (var i=0; i < objects.length; i++) {
var instance = objects[i];
...
}
Ini adalah sebuah iterator untuk NON-jarang daftar di mana indeks dimulai dari 0, yang merupakan skenario ketika berhadapan dengan dokumen.getElementsByTagName atau dokumen.querySelectorAll)
function each( fn, data ) {
if(typeof fn == 'string')
eval('fn = function(data, i){' + fn + '}');
for(var i=0, L=this.length; i < L; i++)
fn.call( this[i], data, i );
return this;
}
Array.prototype.each = each;
Contoh-contoh penggunaan:
Contoh #1
var arr = [];
[1, 2, 3].each( function(a){ a.push( this * this}, arr);
arr = [1, 4, 9]
Contoh #2
each.call(document.getElementsByTagName('p'), "this.className = data;",'blue');
Masing-masing tag p mendapat class="blue"
Contoh #3
each.call(document.getElementsByTagName('p'),
"if( i % 2 == 0) this.className = data;",
'red'
);
Setiap tag p mendapat class="red"
>
Contoh #4
each.call(document.querySelectorAll('p.blue'),
function(newClass, i) {
if( i < 20 )
this.className = newClass;
}, 'green'
);
Dan akhirnya pertama 20 biru p kategori yang berubah menjadi hijau
Hati-hati ketika menggunakan string sebagai fungsi: fungsi dibuat-dari-konteks dan harus digunakan hanya di mana anda tertentu dari variabel scoping. Jika tidak, lebih baik untuk lulus fungsi mana ruang lingkup yang lebih intuitif.
Ada beberapa cara untuk loop melalui array dalam JavaScript, seperti di bawah ini:
untuk - it's salah satu yang paling umum. Full blok kode looping
var languages = ["Java", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>
sementara - loop while kondisi ini melalui. Tampaknya untuk menjadi yang tercepat loop
var text = "";
var i = 0;
while (i < 10) {
text += i + ") something<br>";
i++;
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>
do/while - juga loop melalui blok kode selama kondisi benar, akan dijalankan minimal satu kali
var text = ""
var i = 0;
do {
text += i + ") something <br>";
i++;
}
while (i < 10);
document.getElementById("example").innerHTML = text;
<p id="example"></p>
Fungsionalloop** - forEach
, peta
, filter
, juga mengurangi
(mereka loop melalui fungsi, tetapi mereka digunakan jika anda perlu untuk melakukan sesuatu dengan array, dll.
// For example, in this case we loop through the number and double them up using the map function
var numbers = [65, 44, 12, 4];
document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
<p id="example"></p>
Untuk informasi lebih lanjut dan contoh-contoh soal pemrograman fungsional pada array, melihat posting blog pemrograman Fungsional dalam JavaScript: peta, filter dan mengurangi.
ECMAScript 5 (versi pada JavaScript) untuk bekerja dengan Array:
forEach - Iterates melalui setiap item dalam array dan melakukan apapun yang anda butuhkan dengan masing-masing item.
['C', 'D', 'E'].forEach(function(element, index) {
console.log(element + " is #" + (index+1) + " in the musical scale");
});
// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale
Dalam kasus ini, lebih tertarik pada operasi pada array menggunakan beberapa fitur built-in.
peta - Ini menciptakan sebuah array baru dengan hasil dari fungsi callback. Metode ini baik untuk digunakan ketika anda perlu untuk memformat elemen dari array.
// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
return elem.toUpperCase();
});
// Output: ['BOB', 'JOE', 'JEN']
mengurangi - Seperti namanya, ini mengurangi kenyamanan untuk sebuah nilai tunggal dengan memanggil fungsi yang diberikan lewat di elemen saat ini dan hasil dari eksekusi sebelumnya.
[1,2,3,4].reduce(function(previous, current) {
return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10
setiap - Mengembalikan true atau false jika semua elemen dalam array lulus tes di fungsi callback.
// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];
ages.every(function(elem) {
return elem >= 18;
});
// Output: false
filter - Sangat mirip dengan tiap kecuali bahwa filter mengembalikan sebuah array dengan elemen-elemen yang benar kembali ke fungsi yang diberikan.
// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
return (elem % 2 == 0)
});
// Output: [2,4,6]
Ada's tidak ada built-in kemampuan untuk menembus forEach
. Untuk mengganggu pelaksanaan gunakan Array#beberapa
seperti di bawah ini:
[1,2,3].some(function(number) {
return number === 1;
});
Ini bekerja karena beberapa
kembali benar secepat apapun dari callback, yang dilaksanakan di hotel order, retur benar, hubungan arus pendek eksekusi sisanya.
Original Jawaban
lihat Hotel prototipe untuk beberapa
Saya juga ingin menambahkan ini sebagai komposisi reverse loop dan jawaban di atas bagi seseorang yang ingin sintaks ini juga.
var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
console.log(item);
}
Pro:
Manfaat ini: Anda memiliki referensi yang sudah di pertama seperti itu tidak't harus dinyatakan dengan garis lain. Hal ini berguna ketika perulangan melalui objek array.
Cons:
Hal ini akan mematahkan setiap kali referensi palsu - falsey (undefined, dll.). Hal ini dapat digunakan sebagai keuntungan sekalipun. Namun, hal itu akan membuatnya sedikit lebih sulit untuk dibaca. Dan juga tergantung pada browser ini dapat menjadi "tidak" dioptimalkan untuk bekerja lebih cepat dari yang asli.