Apa metode lintas-browser standar de-facto terbaik untuk menentukan apakah variabel dalam JavaScript adalah larik atau bukan?
Mencari di web ada sejumlah saran berbeda, beberapa bagus dan beberapa tidak valid.
Misalnya, berikut ini adalah pendekatan dasar:
function isArray(obj) {
return (obj && obj.length);
}
Namun, perhatikan apa yang terjadi jika array kosong, atau obj sebenarnya bukan array tetapi mengimplementasikan properti panjang, dll.
Jadi penerapan mana yang terbaik dalam hal benar-benar berfungsi, bersifat lintas-browser, dan masih berkinerja efisien?
javascript
arrays
stpe
sumber
sumber
Jawaban:
Pemeriksaan jenis objek di JS dilakukan melalui
instanceof
, yaituIni tidak akan berfungsi jika objek melewati batas bingkai karena setiap bingkai memiliki
Array
objeknya sendiri . Anda bisa menyiasatinya dengan memeriksa properti internal [[Class]] dari objek. Untuk mendapatkannya, gunakanObject.prototype.toString()
(ini dijamin bekerja oleh ECMA-262):Kedua metode hanya akan bekerja untuk array yang sebenarnya dan bukan objek seperti array seperti
arguments
objek atau daftar node. Karena semua objek yang mirip array harus memilikilength
properti numerik , saya akan memeriksanya seperti ini:Harap dicatat bahwa string akan melewati pemeriksaan ini, yang dapat menyebabkan masalah karena IE tidak mengizinkan akses ke karakter string dengan indeks. Oleh karena itu, Anda mungkin ingin mengubah
typeof obj !== 'undefined'
ketypeof obj === 'object'
mengecualikan primitif dan benda-benda host dengan jenis yang berbeda dari'object'
alltogether. Ini akan tetap membiarkan objek string lewat, yang harus dikecualikan secara manual.Dalam kebanyakan kasus, yang sebenarnya ingin Anda ketahui adalah apakah Anda dapat melakukan iterasi pada objek melalui indeks numerik. Oleh karena itu, sebaiknya periksa apakah objek tersebut memiliki properti bernama
0
, yang bisa dilakukan melalui salah satu pemeriksaan berikut:Cast to object diperlukan untuk bekerja dengan benar untuk primitif mirip-array (yaitu string).
Berikut kode untuk pemeriksaan kuat untuk array JS:
dan objek seperti array yang dapat diulang (yaitu tidak kosong):
sumber
hasOwnProperty
metode, jadi awali sajainstanceof
denganobj.hasOwnProperty &&
; juga, apakah ini masih menjadi masalah dengan IE7? pengujian sederhana saya melalui pengelola tugas menunjukkan bahwa memori diperoleh kembali setelah meminimalkan browser ...Kehadiran ECMAScript Edisi ke-5 memberi kita metode pengujian paling pasti jika variabel adalah array, Array.isArray () :
Meskipun jawaban yang diterima di sini akan berfungsi di seluruh bingkai dan jendela untuk sebagian besar browser, itu tidak untuk Internet Explorer 7 dan yang lebih rendah , karena
Object.prototype.toString
dipanggil pada array dari jendela yang berbeda akan kembali[object Object]
, bukan[object Array]
. IE 9 tampaknya juga telah mundur ke perilaku ini (lihat perbaikan yang diperbarui di bawah).Jika Anda menginginkan solusi yang berfungsi di semua browser, Anda dapat menggunakan:
Ini tidak sepenuhnya tidak bisa dipecahkan, tetapi hanya akan dipatahkan oleh seseorang yang berusaha keras untuk memecahkannya. Ia bekerja di sekitar masalah di IE7 dan yang lebih rendah dan IE9. Bug masih ada di IE 10 PP2 , tetapi mungkin diperbaiki sebelum rilis.
NB, jika Anda tidak yakin tentang solusinya maka saya sarankan Anda mengujinya sesuka hati dan / atau membaca posting blog. Ada solusi potensial lain di sana jika Anda tidak nyaman menggunakan kompilasi bersyarat.
sumber
isArray
tidak mengembalikan true dari array yang dibuat dalam mode dokumen lain? Saya harus memeriksanya ketika saya punya waktu, tetapi menurut saya hal terbaik untuk dilakukan adalah melaporkan bug di Connect sehingga dapat diperbaiki di IE 10.Crockford memiliki dua jawaban di halaman 106 dari "The Good Parts." Yang pertama memeriksa konstruktor, tetapi akan memberikan negatif palsu di seluruh bingkai atau jendela yang berbeda. Ini yang kedua:
Crockford menunjukkan bahwa versi ini akan mengidentifikasi
arguments
array sebagai array, meskipun tidak memiliki metode array apa pun.Pembahasannya yang menarik tentang masalah ini dimulai pada halaman 105.
Ada diskusi menarik lebih lanjut (post-Good Parts) di sini yang meliputi proposal ini:
Semua diskusi membuat saya tidak pernah ingin tahu apakah sesuatu itu array atau tidak.
sumber
jQuery mengimplementasikan fungsi isArray, yang menyarankan cara terbaik untuk melakukannya adalah
(cuplikan diambil dari jQuery v1.3.2 - sedikit disesuaikan agar masuk akal di luar konteks)
sumber
Object.prototype.toString()
- yang cenderung tidak rusakMencuri dari guru John Resig dan jquery:
sumber
typeof
distandarisasi?Apa yang akan Anda lakukan dengan nilai setelah Anda memutuskan itu adalah array?
Misalnya, jika Anda bermaksud untuk menghitung nilai yang terkandung jika terlihat seperti larik ATAU jika itu adalah objek yang digunakan sebagai tabel hash, maka kode berikut mendapatkan apa yang Anda inginkan (kode ini berhenti ketika fungsi penutupan mengembalikan apa pun yang lain dari "undefined". Perhatikan bahwa ini TIDAK mengulang kontainer atau enumerasi COM; yang tersisa sebagai latihan untuk pembaca):
(Catatan: pengujian "o! = Null" untuk null & undefined)
Contoh penggunaan:
sumber
for..in
buruk [tm])for..in
mengulangi properti objek yang tak terhitung banyaknya ; Anda tidak boleh menggunakannya dengan array karena: (1) lambat; (2) tidak ada jaminan untuk menjaga ketertiban; (3) ini akan menyertakan setiap properti yang ditentukan pengguna yang ditetapkan dalam objek atau prototipe apa pun karena ES3 tidak menyertakan cara apa pun untuk menyetel atribut DontEnum; mungkin ada masalah lain yang terlintas di benak sayaJika Anda melakukan ini di CouchDB (SpiderMonkey), gunakan
Array.isArray(array)
sebagai
array.constructor === Array
atauarray instanceof Array
tidak bekerja. Menggunakanarray.toString() === "[object Array]"
memang berhasil tetapi tampaknya cukup cerdik jika dibandingkan.sumber
Jika Anda ingin lintas-browser, Anda menginginkan jQuery.isArray .
sumber
Di w3school ada contoh yang seharusnya cukup standar.
Untuk memeriksa apakah suatu variabel adalah array mereka menggunakan sesuatu yang mirip dengan ini
diuji di Chrome, Firefox, Safari, ie7
sumber
constructor
untuk pemeriksaan tipe imo terlalu rapuh; gunakan salah satu alternatif yang disarankanconstructor
adalah properti DontEnum biasa dari objek prototipe; ini mungkin tidak menjadi masalah untuk tipe built-in selama tidak ada yang melakukan sesuatu yang bodoh, tapi untuk tipe yang ditentukan pengguna bisa dengan mudah; saran saya: selalu gunakaninstanceof
, yang memeriksa rantai prototipe dan tidak bergantung pada properti yang dapat ditimpa secara sewenangSalah satu versi terbaik yang diteliti dan didiskusikan dari fungsi ini dapat ditemukan di situs PHPJS . Anda dapat menautkan ke paket atau Anda dapat langsung membuka fungsinya . Saya sangat merekomendasikan situs ini untuk konstruksi yang setara dengan fungsi PHP di JavaScript.
sumber
Referensi tidak cukup sama dengan konstruktor. Terkadang mereka memiliki referensi konstruktor yang berbeda. Jadi saya menggunakan representasi string dari mereka.
sumber
{constructor:{toString:function(){ return "function Array() { [native code] }"; }}}
Gantikan
Array.isArray(obj)
denganobj.constructor==Array
sampel:
Array('44','55').constructor==Array
kembalikan true (IE8 / Chrome)'55'.constructor==Array
kembali salah (IE8 / Chrome)sumber