instanceof operatori obyektning maâlum bir klassga tegishli yoki yoâqligini tekshirishga imkon beradi. Shuningdek, bu merosni hisobga oladi.
Bunday tekshirish koâp hollarda zarur boâlishi mumkin, bu yerda biz polimorfik funktsiyani yaratish uchun foydalanamiz, bu argumentlarni turiga qarab turlicha koârib chiqadi.
instanceof operator
Sintaksis:
obj instanceof Class;
Agar obj Class ga (yoki undan meros qolgan klassga) tegishli boâlsa, true qiymatini qaytaradi.
Masalan:
class Rabbit {}
let rabbit = new Rabbit();
// bu Rabbit klassning obyektimi?
alert( rabbit instanceof Rabbit ); // true
Shuningdek, u konstruktor funktsiyalari bilan ishlaydi:
// klassning o'rniga
function Rabbit() {}
alert( new Rabbit() instanceof Rabbit ); // true
â¦Va Array singari oârnatilgan klasslar bilan:
let arr = [1, 2, 3];
alert(arr instanceof Array); // true
alert(arr instanceof Object); // true
Iltimos, arr ham Object klassga tegishli ekanligini unutmang. Buning sababi, Array prototip sifatida Object dan meros qilib oladi.
instanceof operatori tekshirish uchun prototip zanjirini taqdiq qiladi va shuningdek, Symbol.hasInstance statik usuli yordamida aniq sozlanadi.
obj instanceof Class algoritmi taxminan quyidagicha ishlaydi:
-
Agar
Symbol.hasInstancestatik usuli boâlsa, bundan foydalaning. Shunga oâxshash:// faraz qiling hamma canEat bu hayvon class Animal { static [Symbol.hasInstance](obj) { if (obj.canEat) return true; } } let obj = { canEat: true }; alert(obj instanceof Animal); // true: Animal[Symbol.hasInstance](obj) chaqirildi -
Koâpgina klasslarda
Symbol.hasInstancemavjud emas. Bunday holda,Class.prototypeprototip zanjiridagi prototiplardan biriga toâgâri keladimi-yoâqligini tekshirib koâring.Boshqacha qilib aytganda, taqqoslang:
obj.__proto__ === Class.prototype? obj.__proto__.__proto__ === Class.prototype? obj.__proto__.__proto__.__proto__ === Class.prototype? ... // if any answer is true, return true // otherwise, if we reached the end of the chain, return falseYuqoridagi misolda
Rabbit.prototype === rabbit.__proto__, shuning uchun darhol javob beradi.Meros boâlsa,
rabbitâ bu ota-ona klassining namunasi:class Animal {} class Rabbit extends Animal {} let rabbit = new Rabbit(); alert(rabbit instanceof Animal); // true // rabbit.__proto__ === Rabbit.prototype // rabbit.__proto__.__proto__ === Animal.prototype (mutanosiblik!)
Quyida rabbit instanceof Animal ning Animal.prototype bilan taqqoslagani tasvirlangan:
Aytgancha, yana bir usul objA.isPrototypeOf(objB), agar objA prototiplar zanjirining bir joyida boâlsa, true ni qaytaradi. Shunday qilib, obj instanceof Class sinovi Class.prototype.isPrototypeOf(obj) sifatida qayta ifodalanishi mumkin.
Bu juda kulgili, lekin Class konstruktorining oâzi tekshirishda qatnashmaydi! Faqat prototiplar zanjiri va Class.prototype muhim ahamiyatga ega.
Bu prototype oâzgartirilganda qiziqarli oqibatlarga olib kelishi mumkin.
Bu yerda boâlgani kabi:
function Rabbit() {}
let rabbit = new Rabbit();
// prototip o'zgartirildi
Rabbit.prototype = {};
// ...endi rabbit emas!
alert( rabbit instanceof Rabbit ); // false
Bu prototype ni oâzgartirmaslikning sabablaridan biridir. Xavfsizlikni saqlash uchun.
Bonus: Object toString turi uchun
Oddiy obyektlar [object Object] massiviga aylantirilishini allaqachon bilamiz:
let obj = {};
alert(obj); // [object Object]
alert(obj.toString()); // bir xil
Bu ularning toString dasturidir. Ammo toString ni aslida undan kuchliroq qiladigan maxfiy xususiyat mavjud. Biz uni kengaytirilgan typeof va instanceof uchun alternativa sifatida ishlatishimiz mumkin.
Gâalati tuyuladimi? Haqiqatdan ham. Keling, demistifikatsiya qilaylik.
Spetsifikatsiya boâyicha oârnatilgan toString obyektdan olinishi va boshqa har qanday qiymat kontekstida bajarilishi mumkin. Va uning natijasi ushbu qiymatga bogâliq.
- Raqam uchun shunday boâladi
[object Number] - Mantiqiy turdagi qiymat uchun bu shunday boâladi
[object Boolean] nulluchun:[object Null]undefineduchun:[object Undefined]- Massivlar uchun:
[object Array] - â¦va hokazo (sozlash mumkin).
Keling, namoyish qilaylik:
// toString usulini qulaylik uchun o'zgaruvchanga nusxalash
let objectToString = Object.prototype.toString;
// bu qanday tur?
let arr = [];
alert(objectToString.call(arr)); // [object Array]
Biz bu yerda call bobda Dekorativlar va ekspeditorlik, call/apply tasvirlanganidek, this=arr kontekstida objectToString funktsiyasini bajarish uchun foydalanganmiz.
Ichkarida, toString algoritmi this ni tekshiradi va tegishli natijani beradi. Koâproq misollar:
let s = Object.prototype.toString;
alert(s.call(123)); // [object Number]
alert(s.call(null)); // [object Null]
alert(s.call(alert)); // [object Function]
Symbol.toStringTag
Obyektning toString xatti-harakatlarini Symbol.toStringTag maxsus obyekt xususiyati yordamida sozlash mumkin.
Masalan:
let user = {
[Symbol.toStringTag]: "User",
};
alert({}.toString.call(user)); // [object User]
Aksariyat atrof-muhit obyektlari uchun bunday xususiyat mavjud. Brauzerga xos bir nechta misol:
// toStringTag atrof-muhitga xos obyekt va klass uchun:
alert(window[Symbol.toStringTag]); // window
alert(XMLHttpRequest.prototype[Symbol.toStringTag]); // XMLHttpRequest
alert({}.toString.call(window)); // [object Window]
alert({}.toString.call(new XMLHttpRequest())); // [object XMLHttpRequest]
Koârib turganingizdek, natija aynan Symbol.toStringTag (agar mavjud boâlsa) boâlib, [object ...] ga oâralgan.
Oxir-oqibat bizda âtypeof steroidlardaâ mavjud boâlib, ular nafaqat maâlumotlarning ibtidoiy turlari uchun, balki oârnatilgan obyektlar uchun ham ishlaydi va hatto ularni sozlash mumkin.
Bu turni faqat tekshirish uchun emas, balki matn sifatida olishni xohlaganimizda, oârnatilgan obyektlar uchun instanceof oârniga ishlatilishi mumkin.
Xulosa
Keling, biz bilgan turlarni tekshirish usullarini takrorlaymiz:
| uchun ishlaydi | qaytaradi | |
|---|---|---|
typeof |
ibtidoiy narsalar | matn |
{}.toString |
ibtidoiy narsalar, oârnatilgan obyektlar, Symbol.toStringTag bilan obyektlar |
matn |
instanceof |
obyektlar | true/false |
Koârib turganimizdek, {}.toString texnik jihatdan âyanada rivojlanganâ typeof dir.
Va instanceof operatori biz klass iyerarxiyasi bilan ishlayotganimizda va merosni hisobga olgan holda klassni tekshirishni xohlaymizda chindan ham porlaydi.
Izohlar
<code>yorlig'ini ishlating, bir nechta satrlar uchun - ularni<pre>yorlig'i bilan o'rab qo'ying, 10 satrdan ortiq bo'lsa - sandbox (plnkr, jsbin, codepenâ¦)