Operator instanceof memungkinkan kita untuk memeriksa apakah suatu object milik class tertentu. instanceof juga memperhatikan inheritance.
Pengecekan seperti itu mungkin diperlukan dalam beberapa kasus. Di sini kita akan menggunakannya untuk membangun fungsi polymorphic, yang memperlakukan argumen secara berbeda bergantung pada tipenya.
Operator instanceof
Sintaksnya adalah:
obj instanceof Class
Akan mengembalikan true jika obj dimiliki oleh Class atau kelas turunannya.
Misalnya:
Itu juga bekerja dengan fungsi constructor:
…Dan kelas bawaan seperti Array:
Harap dicatat bahwa arr juga termasuk dalam kelas Object. Itu karena Array secara prototipikal mewarisi dariObject.
Normalnya, instanceof memeriksa rantai prototype untuk pemeriksaan. Kita juga dapat menyetel custom logic dalam static method Symbol.hasInstance.
Algoritma obj instanceof Class bekerja kurang lebih sebgai berikut:
-
Jika terdapat static method
Symbol.hasInstance, maka panggil saja:Class[Symbol.hasInstance](obj). Itu akan mengembalikantrueataufalse, selesai. Begitulah cara kita bisa menyesuaikan perilaku dariinstanceof.Sebagai contoh:
-
Kebanyakan kelas tidak memiliki
Symbol.hasInstance. Dalam kasus ini, logika standar digunakan:obj instanceOf ClassMemeriksa apakahClass.prototypesama dengan salah satu prototype dalam rantai prototypeobj.Dengan kata lain, bandingkan satu sama lain:
obj.__proto__ === Class.prototype? obj.__proto__.__proto__ === Class.prototype? obj.__proto__.__proto__.__proto__ === Class.prototype? ... // jika jawabannya true, return true // jika tidak, jika kita mencapai ujung rantai, return falsePada contoh diatas
rabbit.__proto__ === Rabbit.prototype, sehingga akan memberikan jawaban segera.Dalam kasus inheritance, kesamaan akan berada pada langkah kedua:
Berikut ilustrasi tentang perbandingan rabbit instanceof Animal dengan Animal.prototype:
Omong-omong, terdapat juga method objA.isPrototypeOf(objB), yang mengembalikan true jika objA berada di suatu tempat dalam rantai prototypes untuk objB. Jadi pengujian obj instanceof Class bisa dirumuskan sebagai Class.prototype.isPrototypeOf(obj).
Ini lucu, tetapi constructor Class itu sendiri tidak ikut dalam pemeriksaan! Hanya rangkaian dari prototype dan Class.prototype yang penting.
Itu bisa menimbulkan konsekuensi yang menarik ketika properti prototype diubah setelah objek dibuat.
Seperti:
Bonus: Object.prototype.toString untuk tipe
Kita tahu bahwa plain object akan diubah menjadi string sebagai [object Object]:
Itulah implementasi dari toString. Tetapi ada fitur tersembunyi yang membuat toString menjadi lebih powerful dari itu. Kita bisa menggunakannya sebagai perluasan dari typeof dan alternatif untuk instanceof.
Terdengar aneh? Tentu. Mari kita cari tahu.
Dengan spesifikasi, toString bawaan dapat diekstrak dari object dan dijalankan dalam konteks nilai lainnya. Dan hasilnya tergantung pada nilai tersebut.
- Untuk angka, akan menjadi
[object Number] - Untuk boolean, akan menjadi
[object Boolean] - Untuk
null:[object Null] - Untuk
undefined:[object Undefined] - Untuk array:
[object Array] - …dll (dapat disesuaikan).
Mari kita tunjukkan:
Disini kita gunakan call seperti dijelaskan dalam bab Decorators dan forwarding, call/apply untuk menjalankan fungsi objectToString dalam konteks this=arr.
Secara internal, algoritme toString memeriksa this dan mengembalikan hasil yang sesuai. Contoh lainnya:
Symbol.toStringTag
Perilaku object toString dapat disesuaikan dengan menggunakan properti objek khusus Symbol.toStringTag.
Sebagai contoh:
Untuk sebagian besar objek yang spesifik pada environment, terdapat properti seperti itu. Berikut beberapa contoh untuk browser yang spesifik:
// toStringTag untuk objek dan kelas yang spesifik pada environtment:
alert( window[Symbol.toStringTag]); // Window
alert( XMLHttpRequest.prototype[Symbol.toStringTag] ); // XMLHttpRequest
alert( {}.toString.call(window) ); // [object Window]
alert( {}.toString.call(new XMLHttpRequest()) ); // [object XMLHttpRequest]
Dapat dilihat, hasilnya persis Symbol.toStringTag (jika ada), digabungkan ke dalam [object ...].
Pada akhirnya kami memiliki “typeof on steroids” yang tidak hanya akan berfungsi untuk tipe data primitif, tetapi juga untuk objek bawaan dan bahkan dapat disesuaikan.
Kita dapat menggunakan {}.toString.call daripada instanceof untuk objek bawaan ketika ingin mendapatkan tipe sebagai string daripada hanya untuk diperiksa.
Ringkasan
Mari kita rangkum metode pengecekan tipe yang kita ketahui:
| bekerja pada | mengembalikan | |
|---|---|---|
typeof |
primitif | string |
{}.toString |
primitif, objek bawaan, objek dengan Symbol.toStringTag |
string |
instanceof |
objek | true/false |
Dapat kita lihat, {}.toString secara teknis “lebih advanced” typeof.
Dan operator instanceof akan lebih berguna ketika kita bekerja dengan hirearki kelas dan ingin memeriksa kelas yang memperhatikan inheritance.