Saya memiliki objek JavaScript seperti berikut:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Sekarang saya ingin loop melalui semua p
elemen ( p1
, p2
, p3
...) dan mendapatkan kunci dan nilai-nilai mereka. Bagaimana saya bisa melakukan itu?
Saya dapat memodifikasi objek JavaScript jika perlu. Tujuan utama saya adalah untuk mengulangi beberapa pasangan nilai kunci dan jika mungkin saya ingin menghindari penggunaan eval
.
javascript
loops
for-loop
each
Tanmoy
sumber
sumber
Jawaban:
Anda dapat menggunakan
for-in
loop seperti yang ditunjukkan oleh orang lain. Namun, Anda juga harus memastikan bahwa kunci yang Anda dapatkan adalah properti sebenarnya dari suatu objek, dan tidak berasal dari prototipe.Berikut cuplikannya:
Alternatif untuk-dengan Object.keys ():
Perhatikan penggunaan
for-of
alih - alihfor-in
, jika tidak digunakan akan kembali tidak ditentukan pada properti bernama, danObject.keys()
memastikan penggunaan hanya properti objek sendiri tanpa seluruh properti rantai prototipeMenggunakan
Object.entries()
metode baru :Catatan: Metode ini tidak didukung secara native oleh Internet Explorer. Anda dapat mempertimbangkan menggunakan Polyfill untuk browser lama.
sumber
alert(key + " -> " + JSON.stringify(p[key]));
__proto__
atauprototype
. Properti ini memiliki referensi ke objek induknya. Objek secara otomatis mewarisi properti dari induknya. Ini adalah alasan penggunaanhasOwnProperty
, yang menandakan bahwa kami tertarik pada objek yang memiliki properti dan bukan properti induknya.Di bawah ECMAScript 5, Anda dapat menggabungkan
Object.keys()
danArray.prototype.forEach()
:ECMAScript 6 menambahkan
for...of
:ECMAScript 8 menambahkan
Object.entries()
yang menghindari keharusan mencari setiap nilai dalam objek asli:Anda dapat menggabungkan
for...of
, merusak, danObject.entries
:Keduanya
Object.keys()
danObject.entries()
iterasi properti dalam urutan yang sama sepertifor...in
loop tetapi abaikan rantai prototipe . Hanya properti enumerable objek sendiri yang diulang.sumber
Object.forEach(obj, function (value, key) {...})
? :( Tentu sajaobj.forEach(function...)
akan lebih pendek dan komplemenArray.prototype.forEach
, tetapi itu akan berisiko memiliki objek menentukanforEach
properti mereka sendiri . Saya kiraObject.keys
penjaga terhadap panggilan balik memodifikasi kunci objek.Object.forEach = function (obj, callback) { Object.keys(obj).forEach(function (key) { callback(obj[key], key); }); }
Object.entries(obj).map/forEach(([key, value]) => console.log(key, value))
([kunci, nilai] adalah destruksi array, untuk mengakses kedua item secara langsung. Dan Anda harus membungkus parameter dalam parens tambahan.)index
kunci di json? Atau jika perlu saya harus menggunakan penghitung yang terpisah?for...of
adalah standar ES6, bukan ES2016.Anda harus menggunakan for-in loop
Tetapi berhati-hatilah saat menggunakan loop semacam ini, karena ini akan mengulang semua properti di sepanjang rantai prototipe .
Oleh karena itu, saat menggunakan loop for-in, selalu gunakan
hasOwnProperty
metode ini untuk menentukan apakah properti saat ini dalam iterasi benar-benar properti objek yang Anda periksa:sumber
{ }
secara pribadi karenaif
tanpa mereka membuatnya sedikit tidak jelas apa yang menjadi bagianif
dan apa yang tidak. Tapi saya kira itu hanya masalah pendapat :){ }
terutama untuk menghindari kebingungan jika nanti perlu menambahkan sesuatu keif
ruang lingkup.Object.prototype.hasOwnProperty.call(p, prop)
Namun, ini juga tidak dapat melindungi terhadap manipulasi Object.prototype ...Pertanyaan tidak akan lengkap jika kita tidak menyebutkan tentang metode alternatif untuk perulangan melalui objek.
Saat ini banyak pustaka JavaScript yang terkenal menyediakan metode mereka sendiri untuk mengulangi koleksi, yaitu lebih dari array , objek , dan objek seperti array . Metode-metode ini nyaman digunakan dan sepenuhnya kompatibel dengan browser apa pun.
Jika Anda bekerja dengan jQuery , Anda dapat menggunakan
jQuery.each()
metode. Ini dapat digunakan untuk beralih mulus pada objek dan array:Di Underscore.js Anda dapat menemukan metode
_.each()
, yang beralih pada daftar elemen, menghasilkan masing-masing pada fungsi yang disediakan (perhatikan urutan argumen dalam fungsi iteratee !):Lo-Dash menyediakan beberapa metode untuk mengulangi properti objek. Dasar
_.forEach()
(atau alias_.each()
) berguna untuk perulangan melalui kedua objek dan array, namun (!) Objek denganlength
properti diperlakukan seperti array, dan untuk menghindari perilaku ini disarankan untuk menggunakan_.forIn()
dan_.forOwn()
metode (ini juga memilikivalue
argumen yang datang terlebih dahulu):_.forIn()
iterate atas properti enumerable milik sendiri dan diwarisi objek, sementara_.forOwn()
iterates hanya atas properti sendiri objek (pada dasarnya memeriksa terhadaphasOwnProperty
fungsi). Untuk objek sederhana dan objek literal, salah satu dari metode ini akan berfungsi dengan baik.Secara umum semua metode yang dijelaskan memiliki perilaku yang sama dengan objek yang disediakan. Selain menggunakan
for..in
loop asli biasanya akan lebih cepat daripada abstraksi apa pun, sepertijQuery.each()
, metode ini jauh lebih mudah digunakan, memerlukan lebih sedikit pengkodean dan memberikan penanganan kesalahan yang lebih baik.sumber
Dalam ECMAScript 5 Anda memiliki pendekatan baru dalam bidang iterasi literal -
Object.keys
Informasi lebih lanjut dapat Anda lihat di MDN
Pilihan saya di bawah ini sebagai solusi yang lebih cepat di versi browser saat ini (Chrome30, IE10, FF25)
Anda dapat membandingkan kinerja dari pendekatan ini dengan implementasi berbeda di jsperf.com :
Dukungan browser dapat Anda lihat di tabel compat Kangax
Untuk browser lama, Anda memiliki polyfill yang sederhana dan lengkap
UPD:
perbandingan kinerja untuk semua kasus paling populer dalam pertanyaan ini pada
perfjs.info
:objek iterasi literal
sumber
Kata pengantar:
Di sini pada tahun 2018, opsi Anda untuk perulangan melalui properti objek adalah (beberapa contoh ikuti daftar):
for-in
[ MDN , spec ] - Struktur lingkaran yang loop melalui nama-nama properti enumerable objek , termasuk yang diwarisi, yang namanya adalah stringObject.keys
[ MDN , spec ] - Fungsi yang menyediakan array nama-nama properti milik sendiri , enumerable properties yang namanya string.Object.values
[ MDN , spesifikasi ] - Sebuah fungsi yang menyediakan sebuah array dari nilai-nilai dari obyek sendiri , enumerable properti.Object.entries
[ MDN , spec ] - Fungsi yang menyediakan larik nama dan nilai properti sendiri , properti yang dapat dihitung (setiap entri dalam larik adalah[name, value]
larik).Object.getOwnPropertyNames
[ MDN , spec ] - Suatu fungsi yang menyediakan larik nama-nama properti objek sendiri (bahkan yang non-enumerable) yang namanya adalah string.Object.getOwnPropertySymbols
[ MDN , spec ] - Suatu fungsi yang menyediakan larik nama-nama properti objek sendiri (bahkan yang non-enumerable) yang namanya Simbol.Reflect.ownKeys
[ MDN , spec ] - Fungsi yang menyediakan array nama-nama objek itu sendiri properti (bahkan yang non-enumerable), baik nama-nama itu string atau Simbol.Object.getPrototypeOf
[ MDN , spesifikasi ] dan penggunaanObject.getOwnPropertyNames
,Object.getOwnPropertySymbols
atauReflect.ownKeys
pada setiap objek dalam rantai prototipe (misalnya di bagian bawah jawaban ini).Dengan mereka semua kecuali
for-in
, Anda akan menggunakan beberapa jenis perulangan membangun pada array (for
,for-of
,forEach
, dll).Contoh:
for-in
:Tampilkan cuplikan kode
Object.keys
(denganfor-of
loop, tetapi Anda dapat menggunakan konstruk looping apa pun) :Tampilkan cuplikan kode
Object.values
:Tampilkan cuplikan kode
Object.entries
:Tampilkan cuplikan kode
Object.getOwnPropertyNames
:Tampilkan cuplikan kode
Object.getOwnPropertySymbols
:Tampilkan cuplikan kode
Reflect.ownKeys
:Tampilkan cuplikan kode
Semua properti , termasuk yang diwarisi non-enumerable:
Tampilkan cuplikan kode
sumber
Anda bisa mengulanginya seperti:
Perhatikan bahwa
key
tidak akan mengambil nilai properti, itu hanya nilai indeks.sumber
Karena es2015 semakin populer, saya memposting jawaban ini yang mencakup penggunaan generator dan iterator untuk secara lancar beralih melalui
[key, value]
pasangan. Karena dimungkinkan dalam bahasa lain misalnya Ruby.Oke, ini kode:
Semua informasi tentang bagaimana Anda bisa melakukan iterator dan generator yang dapat Anda temukan di halaman pengembang Mozilla.
Semoga itu membantu seseorang.
EDIT:
ES2017 akan termasuk
Object.entries
yang akan membuat iterasi[key, value]
pasangan pada objek bahkan lebih mudah. Sekarang diketahui bahwa itu akan menjadi bagian dari standar menurut ts39 informasi tahap .Saya pikir sudah waktunya untuk memperbarui jawaban saya untuk membuatnya menjadi lebih segar daripada sekarang.
Anda dapat menemukan lebih banyak tentang penggunaan di halaman MDN
sumber
Catatan: Anda bisa melakukan ini di atas array, tetapi Anda juga akan mengulanginya di atas
length
dan properti lainnya.sumber
key
hanya akan mengambil nilai indeks, jadi itu hanya akan mengingatkan 0, 1, 2, dll ... Anda perlu mengakses p [kunci].var p = {"p1":"q","p2":"w"}; for(key in p) { alert( key ); }
muncul "p1" dan "p2" di peringatan, jadi apa yang salah tentang itu ???Setelah melihat semua jawaban di sini, hasOwnProperty tidak diperlukan untuk penggunaan saya sendiri karena objek json saya bersih; benar-benar tidak masuk akal dalam menambahkan pemrosesan javascript tambahan. Ini yang saya gunakan:
sumber
Object.prototype
, maka itu akan disebutkan olehfor..in
. Jika Anda yakin tidak menggunakan perpustakaan yang melakukan itu, maka Anda tidak perlu meneleponhasOwnProperty
.Object.create(null)
via prototipe dengan forEach () yang harus melewati properti rantai prototipe :
sumber
obj = { print: 1, each: 2, word: 3 }
menghasilkanTypeError: number is not a function
. MenggunakanforEach
untuk mencocokkanArray
fungsi yang serupa dapat mengurangi risiko.Sangat menarik bahwa orang-orang dalam jawaban ini menyentuh keduanya
Object.keys()
danfor...of
tetapi tidak pernah menggabungkannya:Anda tidak bisa hanya
for...of
sebuahObject
karena itu bukan iterator, danfor...index
atau.forEach()
ingObject.keys()
jelek / tidak efisien.Saya senang kebanyakan orang menahan diri dari
for...in
(dengan atau tanpa memeriksa.hasOwnProperty()
) karena itu juga agak berantakan, jadi selain jawaban saya di atas, saya di sini untuk mengatakan ...Anda dapat membuat asosiasi objek biasa beralih! Berperilaku seperti
Map
dengan penggunaan langsung dari mewahfor...of
DEMO bekerja di Chrome dan FF (saya berasumsi hanya ES6)
Selama Anda memasukkan shim saya di bawah ini:
Tanpa harus membuat objek Peta nyata yang tidak memiliki gula sintaksis yang bagus.
Faktanya, dengan shim ini, jika Anda masih ingin memanfaatkan fungsionalitas Map lainnya (tanpa mengurangi semuanya) tetapi masih ingin menggunakan notasi objek yang rapi, karena objek sekarang dapat diubah, Anda sekarang dapat membuat Peta darinya!
Bagi mereka yang tidak suka shim, atau mengacaukan
prototype
secara umum, jangan ragu untuk membuat fungsi di jendela, menyebutnya sepertigetObjIterator()
itu;Sekarang Anda bisa menyebutnya sebagai fungsi biasa, tidak ada yang terpengaruh
atau
Tidak ada alasan mengapa itu tidak berhasil.
Selamat datang di masa depan.
sumber
For those who don't like to shim, or mess with prototype in general, feel free to make the function on window instead, calling it something like getObjIterator() then;
ordinaryObject
untuk penekanan bahwa sihir masih berfungsi untuk jenis-jenis itu). Apakah Anda memeriksa demo; apa yang tidak berhasil untuk Anda, @ noɥʇʎԀʎzɐɹƆ? (PS gambar profil SE Anda adalah bos)Jadi itu memberikan daftar kunci yang sama seperti yang Anda maksudkan dengan menguji setiap kunci objek dengan hasOwnProperty. Anda tidak memerlukan operasi tes ekstra daripada dan
Object.keys( obj ).forEach(function( key ){})
seharusnya lebih cepat. Mari kita buktikan:Di Firefox saya, saya memiliki hasil sebagai berikut
PS. di Chrome perbedaannya lebih besar http://codepen.io/dsheiko/pen/JdrqXa
PS2: Dalam ES6 (EcmaScript 2015) Anda dapat beralih objek yang lebih baik iterable:
sumber
of
tanpa membuatMap
sBerikut adalah metode lain untuk beralih melalui suatu objek.
sumber
for
metode ini mungkin lebih performan.sumber
Anda juga dapat menggunakan Object.keys () dan beralih di atas kunci objek seperti di bawah ini untuk mendapatkan nilai:
sumber
Hanya kode JavaScript tanpa ketergantungan:
sumber
The
Object.keys()
Metode mengembalikan array properti enumerable objek diberikan sendiri. Baca lebih lanjut di sinisumber
Performa
Hari ini 2020.03.06 Saya melakukan pengujian terhadap solusi yang dipilih pada Chrome v80.0, Safari v13.0.5 dan Firefox 73.0.1 pada MacOs High Sierra v10.13.6
Kesimpulan
for-in
(A, B) cepat (atau tercepat) untuk semua browser untuk objek besar dan kecilfor-of
solusi (H) adalah cepat pada chrome untuk benda kecil dan besari
(J, K) cukup cepat di semua browser untuk objek kecil (untuk firefox juga cepat untuk ojbects besar tetapi sedang cepat di browser lain)Detail
Tes kinerja dilakukan untuk
Cuplikan di bawah ini menyajikan solusi yang digunakan
Tampilkan cuplikan kode
Dan di sini adalah hasil untuk benda kecil di chrome
sumber
Anda dapat menambahkan fungsi forEach sederhana ke semua objek, sehingga Anda dapat secara otomatis mengulangi objek apa pun:
Bagi orang-orang yang tidak menyukai " untuk ... dalam " metode:
Sekarang, Anda dapat menelepon sederhana:
Jika Anda tidak ingin mendapatkan konflik dengan Metode-metode lainnya untuk setiap metode, Anda dapat menamainya dengan nama unik Anda.
sumber
Object
) umumnya dianggap sebagai pola anti karena dapat dengan mudah menyebabkan konflik dengan kode lain. Jadi luka tidak merekomendasikan melakukannya dengan cara ini.Loop bisa sangat menarik saat menggunakan JavaScript murni. Tampaknya hanya ECMA6 (Spesifikasi JavaScript Baru 2015) yang dapat mengendalikan loop. Sayangnya saat saya menulis ini, baik Browser dan lingkungan pengembangan terintegrasi (IDE) masih berjuang untuk mendukung sepenuhnya lonceng dan peluit baru.
Sekilas di sini adalah seperti apa bentuk lingkaran objek JavaScript sebelum ECMA6:
Juga, saya tahu ini di luar ruang lingkup dengan pertanyaan ini tetapi pada tahun 2011, ECMAScript 5.1 menambahkan
forEach
metode hanya untuk Array yang pada dasarnya menciptakan cara baru yang ditingkatkan untuk loop melalui array sementara masih meninggalkan objek yang tidak dapat diubah dengan verbose yang lama danfor
loop yang membingungkan . Tetapi bagian yang aneh adalah bahwaforEach
metode baru ini tidak mendukungbreak
yang menyebabkan semua jenis masalah lainnya.Pada dasarnya di 2011, tidak ada cara yang benar-benar solid untuk mengulang JavaScript selain dari apa yang banyak perpustakaan populer (jQuery, Underscore, dll.) Memutuskan untuk menerapkan kembali.
Pada 2015, kami sekarang memiliki cara yang lebih baik di luar kotak untuk mengulang (dan memecah) semua jenis objek (termasuk Array dan Strings). Berikut adalah tampilan loop dalam JavaScript ketika rekomendasi menjadi arus utama:
Perhatikan bahwa sebagian besar browser tidak akan mendukung kode di atas pada 18 Juni 2016. Bahkan di Chrome Anda harus mengaktifkan tanda khusus ini agar dapat berfungsi:
chrome://flags/#enable-javascript-harmony
Sampai ini menjadi standar baru, metode lama masih dapat digunakan tetapi ada juga alternatif di perpustakaan populer atau bahkan alternatif ringan bagi mereka yang tidak menggunakan perpustakaan ini.
sumber
Uncaught TypeError: Object.entries is not a function
. Apakah ini belum diterapkan di chrome?Dalam ES6 kami memiliki simbol terkenal untuk mengekspos beberapa metode internal sebelumnya, Anda dapat menggunakannya untuk menentukan bagaimana iterator bekerja untuk objek ini:
ini akan memberikan hasil yang sama seperti menggunakan for ... di es6 loop.
Tetapi penting untuk mengetahui kemampuan yang sekarang Anda miliki menggunakan es6!
sumber
Object.keys()
dan dialokasikan dalam memori ... Keren!Saya akan melakukan ini daripada memeriksa
obj.hasOwnerProperty
dalam setiapfor ... in
loop.sumber
sumber
json = [{"key1":"value1","key2":"value2"},{"key1":"value3","key2":"value4"}] for (var i = 0; i < json.length; i++) { for (var key in json[i]) { if (json[i].hasOwnProperty(key)) { console.log(key + " -> " + json[i][key]); } } }
Menggunakan
for-of
onObject.keys()
Suka:
sumber
Jika Anda ingin mengulangi juga properti yang tidak dapat dihitung , Anda dapat menggunakan
Object.getOwnPropertyNames(obj)
untuk mengembalikan array semua properti (yang dapat dihitung atau tidak) yang ditemukan langsung pada objek yang diberikan.sumber
Error
objek dan tidak bisa mendapatkan properti dalam satu lingkaran atau_.forIn(err)
panggilan. MenggunakanObject.getOwnPropertyNames(err)
memungkinkan saya untuk mengakses semua bagianError
yang tidak bisa saya dapatkan sebelumnya. Terima kasih!Jika ada yang perlu mengulang melalui arrayObjects dengan kondisi :
sumber
Mempertimbangkan ES6 Saya ingin menambahkan sendok gula saya sendiri dan memberikan satu pendekatan lagi untuk beralih pada sifat-sifat objek.
Karena objek JS biasa tidak dapat diubah hanya di luar kotak, kami tidak dapat menggunakan
for..of
loop untuk mengulangi kontennya. Tapi tidak ada yang bisa menghentikan kita untuk membuatnya lebih baik .Mari kita punya
book
objek.Karena kita sudah membuatnya kita bisa menggunakannya dengan cara ini:
Atau jika Anda mengetahui kekuatan generator ES6 , maka Anda tentu dapat membuat kode di atas jauh lebih pendek.
Tentu, Anda dapat menerapkan perilaku seperti itu untuk semua objek dengan membuatnya tingkat di
Object
atasprototype
.Juga, objek yang mematuhi protokol iterable dapat digunakan dengan operator penyebaran fitur ES2015 baru sehingga kita dapat membaca nilai properti objek sebagai array.
Atau Anda dapat menggunakan destructuring tugas:
Anda dapat memeriksa JSFiddle dengan semua kode yang saya berikan di atas.
sumber
karena ES06 Anda bisa mendapatkan nilai-nilai objek dengan array
mengembalikan array nilai objek dan tidak mengekstrak nilai dari Prototipe !!
Object.values MDN DOCS ()
dan untuk kunci (sudah ada jawab sebelum saya di sini)
sumber
Dalam skrip ES terbaru, Anda dapat melakukan sesuatu seperti ini:
sumber