Dalam dokumen MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
The for...of
membangun digambarkan untuk dapat iterate atas "iterable" objek. Tetapi apakah ada cara yang baik untuk memutuskan apakah suatu objek dapat diulang?
Saya telah mencoba menemukan properti umum untuk array, iterator, dan generator, tetapi tidak dapat melakukannya.
Selain melakukan for ... of
blok percobaan dan memeriksa kesalahan jenis, apakah ada cara yang bersih untuk melakukan ini?
javascript
simonzack
sumber
sumber
iterator()
metode. ". Namun, karena ini adalah draf, hanya pemeriksaan yang mungkin bergantung pada penerapan. Lingkungan apa yang Anda gunakan?Jawaban:
Cara yang tepat untuk memeriksa iterabilitas adalah sebagai berikut:
Mengapa ini berfungsi (protokol yang dapat diulang secara mendalam): https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Iteration_protocols
Karena kita berbicara tentang untuk..dari, saya berasumsi, kita berada dalam pola pikir ES6.
Juga, jangan kaget bahwa fungsi ini mengembalikan
true
jikaobj
adalah sebuah string, sebagai string yang mengulangi karakternya.sumber
Symbol.iterator in Object(obj)
,.return typeof obj[Symbol.iterator] === 'function'
? "Agar dapat diulang, objek harus mengimplementasikan metode @@ iterator" - ini menentukan metodetypeof Object(obj)[Symbol.iterator] === 'function'
berhasil dalam semua kasus?Mengapa begitu bertele-tele?
sumber
Readability > Cleverness
selalu kembalitrue
.Readability > Cleverness
, jadi mempersingkat variabelobject
untuko
tidak membantu siapa pun. 2. String kosong''
dapat diulang dan karena itu harus dikembalikantrue
.!= null
Solusi paling sederhana sebenarnya adalah ini:
Object
akan membungkus apa pun yang bukan objek menjadi satu, memungkinkanin
operator untuk bekerja bahkan jika nilai aslinya bukan Objek.null
danundefined
diubah menjadi objek kosong sehingga tidak perlu deteksi kasus tepi, dan string dibungkus menjadi objek String yang dapat diulang.sumber
Symbol.iterator
.Object
sia-sia untuk jenis pemeriksaan ini.Object
fungsi diimplementasikan, tetapi itu hanya membuat objek baru jikavalue
belum menjadi objek. Saya berharap kombinasi dariin
danObject(...)
menjadi sesuatu yang dapat dioptimalkan dengan mudah oleh mesin browser, tidak seperti yang dikatakanvalue !== undefined && value !== null && value[Symbol.iterator] && true
. Plus, ini sangat mudah dibaca, yang saya pedulikan.Sebagai catatan samping, HATI - HATI tentang definisi iterable . Jika Anda datang dari bahasa lain Anda akan berharap bahwa sesuatu yang Anda dapat beralih di atas dengan, mengatakan, sebuah
for
loop iterable . Saya khawatir itu tidak terjadi di sini di mana iterable berarti sesuatu yang mengimplementasikan protokol iterasi .Untuk memperjelas semua contoh di atas mengembalikan
false
objek ini{a: 1, b: 2}
karena objek itu tidak mengimplementasikan protokol iterasi. Jadi, Anda tidak akan dapat mengulanginya denganfor...of
TETAPI Anda masih bisa melakukannya dengan filefor...in
.Jadi, jika Anda ingin menghindari kesalahan yang menyakitkan buat kode Anda lebih spesifik dengan mengganti nama metode Anda seperti yang ditunjukkan di bawah ini:
sumber
undefined
?object !== null
dalam jawaban Anda tetapi Anda melakukannyaobject != null
sehingga tidak melanggarundefined
dalam kasus khusus itu. Saya telah memperbarui jawaban saya.hasIterationProtocol('')
harus kembalitrue
! Bagaimana kalau Anda menghapus kode Anda dan biarkan saja bagian penjelasan yang berulang, yang merupakan satu-satunya hal yang menambah nilai nyata / sesuatu yang baru dalam jawaban Anda.true
, dengan menghapus sebagian dari jawaban lama saya menggabungkan kedua fungsi dan lupa tentang perbandingan yang ketat. Sekarang saya mengembalikan jawaban asli yang berfungsi dengan baik.Object(...)
, tangkapan yang bagus. Tetapi dalam kasus ini pemeriksaan null tidak diperlukan.Saat ini, seperti yang telah disebutkan, untuk menguji apakah
obj
iterable lakukan sajaJawaban historis (tidak lagi valid)
The
for..of
konstruk merupakan bagian dari ECMAScript edisi 6 Bahasa Keterangan Draft. Jadi bisa berubah sebelum versi final.Dalam draf ini, objek yang dapat diulang harus memiliki fungsi
iterator
sebagai properti.Anda dapat memeriksa apakah suatu objek dapat diulang seperti ini:
sumber
Untuk iterator asinkron, Anda harus memeriksa 'Symbol.asyncIterator', bukan 'Symbol.iterator':
sumber
Jika Anda ingin memeriksa apakah suatu variabel adalah object (
{key: value}
) atau array ([value, value]
), Anda dapat melakukan itu:sumber