Dalam kasus khusus saya:
callback instanceof Function
atau
typeof callback == "function"
apakah itu penting, apa bedanya?
Sumber Daya Tambahan:
JavaScript-Taman typeof vs instanceof
javascript
instanceof
typeof
farinspace
sumber
sumber
Object.prototype.toString
ecma-international.org/ecma-262/6.0/….constructor
properti saja.Jawaban:
Gunakan
instanceof
untuk jenis khusus:Gunakan
typeof
untuk tipe bawaan yang sederhana:Gunakan
instanceof
untuk tipe bawaan yang rumit:Dan yang terakhir agak rumit:
sumber
Use instanceof for complex built in types
- ini masih rentan terhadap kesalahan. Lebih baik menggunakan ES5Array.isArray()
et al. atau shims yang direkomendasikan.Keduanya sama dalam fungsionalitas karena mereka berdua mengembalikan informasi tipe, namun saya pribadi lebih suka
instanceof
karena membandingkan tipe yang sebenarnya daripada string. Perbandingan jenis kurang rentan terhadap kesalahan manusia, dan secara teknis lebih cepat karena membandingkan pointer dalam memori daripada melakukan perbandingan seluruh string.sumber
Alasan yang baik untuk menggunakan typeof adalah jika variabel mungkin tidak terdefinisi.
Alasan yang baik untuk menggunakan instanceof adalah jika variabel mungkin nol.
Jadi menurut saya, itu tergantung pada jenis data apa yang Anda periksa.
sumber
instanceof
tidak dapat dibandingkan dengan tipe primitif, typeof bisa.undefined instanceof Object
mengembalikan false, dan tidak melempar pengecualian. Saya tidak tahu seberapa baru perubahan itu, tetapi itu membuatinstanceof
lebih menarik.undefined instanceof Object
tidak melempar pengecualian karena, eh,undefined
didefinisikan. Konstanta ada di namespace. Ketika suatu variabel tidak ada (karena kesalahan ketik misalnya), instanceof akan melemparkan pengecualian. Menggunakan typeof pada variabel yang tidak ada menghasilkan 'tidak terdefinisi' di sisi lain.Untuk memperjelas, Anda perlu mengetahui dua fakta:
Object.setPrototypeOf()
metode (ECMAScript 2015) atau oleh__proto__
properti (browser lama, usang). Mengubah prototipe suatu objek tidak dianjurkan, karena masalah kinerja.Jadi instanceof hanya berlaku untuk objek. Dalam kebanyakan kasus, Anda tidak menggunakan konstruktor untuk membuat string atau angka. Kamu bisa. Tetapi Anda hampir tidak pernah melakukannya.
Juga instanceof tidak dapat memeriksa, konstruktor mana yang digunakan untuk membuat objek, tetapi akan mengembalikan true, bahkan jika objek berasal dari kelas yang diperiksa. Dalam kebanyakan kasus ini adalah perilaku yang diinginkan, tetapi kadang-kadang tidak. Jadi, Anda perlu menjaga pikiran itu.
Masalah lain adalah bahwa cakupan yang berbeda memiliki lingkungan eksekusi yang berbeda. Ini berarti bahwa mereka memiliki built-in yang berbeda (objek global yang berbeda, konstruktor yang berbeda, dll.). Ini dapat menghasilkan hasil yang tidak terduga.
Misalnya,
[] instanceof window.frames[0].Array
akan kembalifalse
, karenaArray.prototype !== window.frames[0].Array
dan array mewarisi dari yang sebelumnya.Selain itu, tidak dapat digunakan pada nilai yang tidak ditentukan, karena tidak memiliki prototipe.
Sekarang mari kita bicara tentang satu hal yang rumit. Bagaimana jika Anda menggunakan konstruktor untuk membuat tipe primitif?
Sepertinya sihir. Tapi ternyata tidak. Ini disebut tinju (membungkus nilai primitif dengan objek) dan unboxing (mengekstraksi nilai primitif yang dibungkus dari objek). Kode semacam itu tampaknya rapuh "sedikit". Tentu saja Anda bisa menghindari membuat tipe primitif dengan konstruktor. Tetapi ada situasi lain yang mungkin terjadi, ketika tinju bisa mengenai Anda. Saat Anda menggunakan Function.call () atau Function.apply () pada tipe primitif.
Untuk menghindari ini, Anda dapat menggunakan mode ketat:
upd: Sejak ECMAScript 2015, ada satu jenis lagi yang disebut Simbol, yang memiliki typeof sendiri == "simbol" .
Anda dapat membacanya di MDN: ( Simbol , typeof ).
sumber
if an object is created by a given constructor
Ini salah.o instanceof C
akan mengembalikan true jika o mewarisi dari C.prototype. Anda telah menyebutkan sesuatu tentang ini nanti dalam jawaban Anda tetapi tidak terlalu jelas.Saya telah menemukan beberapa perilaku yang sangat menarik (dibaca sebagai "mengerikan") di Safari 5 dan Internet Explorer 9. Saya menggunakan ini dengan sangat sukses di Chrome dan Firefox.
Lalu saya uji di IE9, dan tidak berfungsi sama sekali. Kejutan besar. Tapi di Safari, itu terputus-putus! Jadi saya mulai men-debug, dan saya menemukan bahwa Internet Explorer selalu kembali
false
. Tapi hal yang paling aneh adalah bahwa Safari tampaknya akan melakukan beberapa jenis optimasi di nya VM JavaScript di mana itu adalahtrue
yang pertama kalinya, tapifalse
setiap kali anda menekan ulang!Otak saya hampir meledak.
Jadi sekarang saya sudah sepakat:
Dan sekarang semuanya bekerja dengan baik. Perhatikan bahwa Anda dapat menelepon
"a string".toString()
dan hanya mengembalikan salinan string, yaituJadi saya akan menggunakan keduanya mulai sekarang.
sumber
Perbedaan praktis signifikan lainnya:
sumber
instanceof
juga berfungsi ketikacallback
subtipeFunction
, saya pikirsumber
instanceof
di Javascript bisa bersisik - saya percaya kerangka kerja utama mencoba untuk menghindari penggunaannya. Jendela yang berbeda adalah salah satu cara untuk memecahkannya - Saya percaya hierarki kelas dapat membingungkannya juga.Ada cara yang lebih baik untuk menguji apakah suatu objek adalah tipe bawaan tertentu (yang biasanya Anda inginkan). Buat fungsi utilitas dan gunakan:
Dan seterusnya.
sumber
instanceof
tidak akan bekerja untuk primitif misalnya"foo" instanceof String
akan kembalifalse
sedangkantypeof "foo" == "string"
akan kembalitrue
.Di sisi lain
typeof
mungkin tidak akan melakukan apa yang Anda inginkan ketika datang ke objek khusus (atau kelas, apa pun yang Anda ingin menyebutnya). Sebagai contoh:Kebetulan fungsi keduanya adalah 'fungsi' primitif dan turunan dari 'Function', yang sedikit aneh karena tidak berfungsi seperti itu untuk tipe primitif lainnya misalnya.
tapi
sumber
Saya akan merekomendasikan menggunakan prototipe
callback.isFunction()
.Mereka telah menemukan perbedaannya dan Anda dapat mengandalkan alasan mereka.
Saya kira kerangka kerja JS lainnya memiliki hal-hal seperti itu juga.
instanceOf
tidak akan bekerja pada fungsi yang didefinisikan di windows lain, saya percaya. Fungsinya berbeda dari Andawindow.Function
.sumber
Saat memeriksa fungsi, seseorang harus selalu menggunakan
typeof
.Inilah perbedaannya:
Inilah sebabnya mengapa seseorang tidak boleh menggunakan
instanceof
untuk memeriksa suatu fungsi.sumber
typeof
yang salah -f
semuanya adalah sebagai berikut:Object
(objek) danFunction
(fungsi). Kecuali bagi saya itu lebih masuk akal untuk digunakaninstanceof
karena mengetahui bahwa itu adalah fungsi saya tahu itu adalah objek juga, karena semua fungsi adalah objek dalam ECMAScript. Kebalikannya tidak benar - mengetahui daritypeof
ituf
memangobject
saya tidak tahu itu juga berfungsi.length
,name
dancall
dari Function, tetapi semuanya tidak berfungsi. Yang lebih parah, hal itu tidak bisa disebut danTypeError
mengatakan:f is not a function
.Perbedaan praktis yang signifikan:
Jangan tanya kenapa.
sumber
str
adalah string primitif, bukan objek string. Hal yang sama berlaku untuk primitif bilangan dan boolean primitif, mereka bukan contoh dari rekan "dibangun", objek String, Number dan Boolean. JavaScript secara otomatis mengubah ketiga primitif ini menjadi objek bila diperlukan (seperti memanfaatkan metode pada rantai prototipe objek). Di sisi lain dari perbedaan praktis Anda, instanceof lebih baik untuk memeriksa array sejak itutypeof [] == "object" // true
.Performa
typeof
lebih cepat daripadainstanceof
dalam situasi di mana keduanya berlaku.Tergantung pada mesin Anda, perbedaan kinerja yang mendukung
typeof
bisa sekitar 20% . ( Jarak tempuh Anda mungkin beragam )Berikut ini adalah pengujian benchmark untuk
Array
:Hasil
sumber
instanceof
selalu mengikuti rantai prototipe objek, sehingga penalti kinerja akan tergantung pada seberapa jauh dalam rantai prototipe kelas,instanceof
diuji terhadap. Jadi untuk rantai pewarisan pendek, penalti akan lebih rendah (seperti[] instanceof Array
,,{} instanceof Object
), dan untuk jangka panjang - lebih besar. Jadi, jika keduanyaobj instanceof SomeClass
dantypeof obj !== 'string'
artinya sama dari perspektif beberapa kode hipotetis Anda (misalnya, jika Anda hanya melakukan tesif
, dan tidakswitch
melakukan beberapa kelas dll), maka Anda sebaiknya memilih yang kedua, berdasarkan kinerja,Ini hanya pengetahuan pelengkap untuk semua penjelasan lainnya di sini - saya tidak menyarankan untuk digunakan di
.constructor
mana-mana.TL; DR: Dalam situasi di mana
typeof
bukan merupakan pilihan, dan ketika Anda tahu bahwa Anda tidak peduli dengan rantai prototipe ,Object.prototype.constructor
bisa menjadi alternatif yang lebih baik atau bahkan lebih baik daripadainstanceof
:Sudah dalam standar sejak 1.1, jadi jangan khawatir tentang kompatibilitas mundur.
Muhammad Umer secara singkat menyebutkan ini dalam komentar di suatu tempat di sini juga. Ini bekerja pada semuanya dengan prototipe - jadi semuanya tidak
null
atauundefined
:Selain itu, tergantung pada kasus penggunaan Anda, ini bisa menjadi jauh lebih cepat daripada
instanceof
(alasannya adalah karena tidak perlu memeriksa seluruh rantai prototipe). Dalam kasus saya, saya membutuhkan cara cepat untuk memeriksa apakah suatu nilai adalah array yang diketik:https://run.perf.zone/view/isTypedArray-constructor-vs-instanceof-1519140393812
Dan hasilnya:
Chrome 64.0.3282.167 (64-bit, Windows)
Firefox 59.0b10 (64-bit, Windows)
Karena penasaran, saya melakukan benchmark cepat terhadap mainan
typeof
; secara mengejutkan itu tidak berkinerja jauh lebih buruk, dan tampaknya bahkan lebih cepat di Chrome:https://run.perf.zone/view/typeof-vs-constructor-string-or-number-1519142623570
CATATAN: Urutan di mana fungsi yang terdaftar akan beralih di antara gambar!
Chrome 64.0.3282.167 (64-bit, Windows)
Firefox 59.0b10 (64-bit, Windows)
CATATAN: Urutan di mana fungsi yang terdaftar akan beralih di antara gambar!
sumber
Gunakan instanceof karena jika Anda mengubah nama kelas Anda akan mendapatkan kesalahan kompilator.
sumber
sumber
Saya berasal dari pengasuhan OO yang ketat
String rentan terhadap salah ejaan saya atau kesalahan ketik lainnya. Ditambah lagi, saya merasa ini lebih baik.
sumber
Meskipun instanceof mungkin sedikit lebih cepat daripada typeof , saya lebih suka yang kedua karena sihir yang mungkin:
sumber
Satu kasus lagi adalah bahwa Anda hanya dapat menyusun
instanceof
- itu mengembalikan benar atau salah. Dengantypeof
Anda bisa mendapatkan jenis sesuatu yang disediakansumber
dengan mempertimbangkan kinerja, Anda sebaiknya menggunakan typeof dengan perangkat keras tipikal, jika Anda membuat skrip dengan loop 10 juta iterasi instruksi: typeof str == 'string' akan memakan waktu 9ms sementara 'string' instanceof String akan mengambil 19ms
sumber
Tentu saja itu penting ........!
Mari kita berjalan dengan contoh-contoh ini. Dalam contoh kita, kita akan mendeklarasikan fungsi dengan dua cara berbeda.
Kami akan menggunakan keduanya
function declaration
dan Function Constructor . Kami akan melihat bagaimanatypeof
daninstanceof
berperilaku dalam dua skenario yang berbeda.Buat fungsi menggunakan deklarasi fungsi:
Penjelasan yang mungkin untuk hasil yang berbeda tersebut adalah, ketika kami membuat deklarasi fungsi,
typeof
dapat memahami bahwa itu adalah sebuah fungsi. Karenatypeof
memeriksa apakah ekspresi pada tipe operasi beroperasi, dalam kasus kami diimplementasikan Metode Panggilan atau tidak . Jika menerapkan metode itu adalah fungsi. Sebaliknya tidak. Untuk klarifikasi periksa spesifikasi ecmascript untuk typeof .MyFunc
Call
Buat fungsi menggunakan fungsi konstruktor:
Di sini
typeof
menegaskan bahwa ituMyFunc2
adalah fungsi sertainstanceof
operator. Kami sudah tahutypeof
memeriksa apakah metode yangMyFunc2
diterapkanCall
atau tidak. SepertiMyFunc2
fungsi dan menerapkancall
metode, itulah caratypeof
mengetahui bahwa itu adalah fungsi. Di sisi lain, kami dulufunction constructor
membuatMyFunc2
, menjadi contoh dariFunction constructor
. Itulah sebabnyainstanceof
juga memutuskan untuktrue
.Apa yang lebih aman untuk digunakan?
Seperti yang dapat kita lihat dalam kedua kasus,
typeof
operator dapat dengan sukses menyatakan bahwa kita berurusan dengan suatu fungsi di sini, itu lebih aman daripadainstanceof
.instanceof
akan gagal dalam kasusfunction declaration
karenafunction declarations
bukan merupakan contohFunction constructor
.Praktek terbaik :
Seperti yang disarankan Gary Rafferty , cara terbaik harus menggunakan kedua typeof dan instanceof bersama-sama.
sumber
Untuk menjadi contoh yang sangat tepat harus digunakan di mana nilai dibuat melalui konstruktor (umumnya tipe khusus) untuk misalnya
sedangkan typeof untuk memeriksa nilai yang dibuat hanya dengan tugas misalnya
sumber
tidak perlu kewalahan dengan banyak contoh di atas, hanya perlu diingat dua sudut pandang:
typeof var;
adalah operator unary akan mengembalikan tipe asli atau jenis root var. sehingga akan kembali tipe primitif (string
,number
,bigint
,boolean
,undefined
, dansymbol
) atauobject
jenis.dalam kasus objek tingkat yang lebih tinggi, seperti objek bawaan (String, Number, Boolean, Array ..) atau objek kompleks atau kustom, semuanya adalah
object
tipe root, tetapi tipe instance base yang dibangun pada mereka berbeda-beda (seperti kelas OOP konsep pewarisan), di sinia instanceof A
- operator biner - akan membantu Anda, itu akan melalui rantai prototipe untuk memeriksa apakah konstruktor dari operan yang tepat (A) muncul atau tidak.jadi setiap kali Anda ingin memeriksa "tipe root" atau bekerja dengan variabel primitif - gunakan "typeof", jika tidak gunakan "instanceof".
null
adalah kasus khusus, yang tampaknya primitif, tetapi memang merupakan kasus khusus untuk objek. Menggunakana === null
untuk memeriksa null sebagai gantinya.di sisi lain,
function
juga merupakan kasus khusus, yang merupakan objek bawaantypeof
kembalifunction
seperti yang Anda lihat
instanceof
harus melalui rantai prototipe sementara itutypeof
hanya memeriksa jenis root satu kali sehingga mudah untuk memahami mengapatypeof
lebih cepat daripadainstanceof
sumber
Menurut dokumentasi MDN tentang typeof , objek yang dipakai dengan kata kunci "baru" adalah dari tipe 'objek':
Sedangkan dokumentasi tentang instance poin itu:
Jadi jika seseorang ingin memeriksa misalnya bahwa sesuatu adalah string tidak peduli bagaimana itu dibuat, pendekatan teraman akan digunakan
instanceof
.sumber