Saat menilai tipe fungsi, kita biasanya menggunakan metode typeof. Dalam keadaan normal, ini akan mendapatkan efek yang kita harapkan. Namun, ada beberapa detail yang belum kami ketahui. Setelah menganalisis detail ini, John Resig memberi kami solusi sempurna, yang akan diperkenalkan secara detail di artikel ini:
1. Detail metode tradisional yang tidak diketahui
Tidak dapat dipungkiri bahwa dalam menentukan tipe fungsi, kita menggunakan metode typeof, seperti:
fungsi fn(){
//isi
}
alert(typeof fn)//Hasilnya adalah "fungsi".
Namun, metode ini tidak berfungsi seperti yang diharapkan di beberapa browser.
1. Firefox2 dan Firefox3
Di kedua browser ini, penggunaan typeof untuk mendeteksi tipe elemen objek HTML menghasilkan hasil "fungsi" yang tidak tepat, bukan "objek", seperti HTMLDocument. menyukai:
peringatan(jenis Dokumen HTML);
//Di Firefox2 hasilnya adalah "fungsi";
//Di Firefox3 hasilnya adalah "objek";
2. Firefox2
Untuk ekspresi reguler, hasil yang dikembalikan di browser ini adalah "fungsi" (hasilnya adalah "objek" di Firefox3), seperti:
var reg = /tes/;
peringatan(jenis reg);
//Di Firefox2 hasilnya adalah "fungsi";
//Di Firefox3 hasilnya adalah "objek";
Catatan: Saya mengujinya di Safari, dan hasilnya juga "berfungsi".
3. IE6 dan IE7
Saat menggunakan metode typeof pada elemen DOM di IE, hasilnya adalah "objek". menyukai:
peringatan(typeof document.getElementsByTagName("body")[0].getAttribute);
//Hasilnya adalah "objek"
4.Safari 3
Safari menganggap bahwa NodeList elemen DOM adalah sebuah fungsi, seperti:
alert(typeof document.body.childNodes);
//Hasilnya adalah "fungsi"
Jelasnya, jika Anda ingin menguji apakah suatu objek merupakan suatu fungsi, menggunakan metode typeof tidak menjamin hasil pengujian yang sebenarnya. Maka diperlukan solusi yang menjamin hasil pengujian di semua browser. Kita tahu bahwa fungsi itu sendiri memiliki dua metode, apply() dan call(), namun kedua metode ini tidak ada dalam fungsi bermasalah di IE.
peringatan(typeof document.getElementsByTagName("body")[0].getAttribute.call)
//Hasilnya "tidak terdefinisi" di IE
Jelas kita tidak bisa memanfaatkan kedua cara ini.
2. Solusi sempurna dan proses implementasi
John Resig memberi kita solusi sempurna. Metode yang kompleks namun stabil untuk menentukan apakah suatu objek merupakan suatu fungsi adalah sebagai berikut:
fungsi isFunction( fn ) {
kembali !!fn && !fn.nodeName && fn.konstruktor != String &&
fn.konstruktor != RegExp && fn.konstruktor != Array &&
/fungsi/i.test( fn + "" );
}
Fungsi ini pertama-tama memastikan bahwa objek pengujian ada dan membuat serialnya menjadi string yang berisi "fungsi". Ini adalah dasar deteksi kami (fn.constructor != String, fn.constructor != Array, dan fn.constructor != RegExp ) . Selain itu, kita perlu memastikan bahwa fungsi yang dideklarasikan bukan node DOM (fn.nodeName). Kemudian, kita bisa melakukan tes toString. Jika kita mengonversi suatu fungsi menjadi string, di browser (fn+"") memberi kita hasil seperti ini "nama fungsi(){...}". Sekarang, menentukan apakah suatu fungsi adalah semudah memeriksa apakah string tersebut mengandung kata "fungsi". Ini bekerja dengan sangat baik, untuk fungsi apa pun yang dimaksud, kami mendapatkan hasil yang kami perlukan di semua browser. Dibandingkan dengan metode tradisional, kecepatan pengoperasian fungsi ini agak kurang memuaskan. Penulis menyarankan agar kita menggunakannya secara konservatif.
John Resig adalah pengembang perpustakaan jQuery. Saya yakin teman-teman yang menggunakan perpustakaan ini sudah familiar dengan sintaksisnya yang ringkas dan kinerjanya yang luar biasa. Selain mengejar kesederhanaan kode dan kinerja tinggi, semangat kesempurnaan penulis juga mengesankan. Jika Anda seorang perfeksionis, saya yakin artikel ini akan bermanfaat bagi Anda.
Teks asli: http://www.denisdeng.com/?p=426