ÐпеÑаÑÐ¾Ñ instanceof дозволÑÑ Ð¿ÐµÑевÑÑиÑи, Ñи належиÑÑ Ð¾Ð±âÑÐºÑ Ð´Ð¾ певного клаÑÑ. ÐÑн Ñакож вÑаÑ
овÑÑ Ð½Ð°ÑлÑдÑваннÑ.
Така пеÑевÑÑка може знадобиÑиÑÑ Ð² багаÑÑÐ¾Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÐ°Ñ . ÐапÑиклад, його можна викоÑиÑÑаÑи Ð´Ð»Ñ ÑÑвоÑÐµÐ½Ð½Ñ Ð¿Ð¾Ð»ÑмоÑÑÐ½Ð¾Ñ ÑÑнкÑÑÑ, Ñка обÑоблÑÑ Ð°ÑгÑменÑи по-ÑÑÐ·Ð½Ð¾Ð¼Ñ Ð·Ð°Ð»ÐµÐ¶Ð½Ð¾ вÑд ÑÑ ÑипÑ.
ÐпеÑаÑÐ¾Ñ instanceof
СинÑакÑÐ¸Ñ Ñакий:
obj instanceof Class
ÐÑн повеÑÑÐ°Ñ true, ÑкÑо obj належиÑÑ Ð´Ð¾ клаÑÑ Class або клаÑÑ, Ñкий наÑлÑдÑÑÑÑÑÑ Ð²Ñд нÑого.
ÐапÑиклад:
class Rabbit {}
let rabbit = new Rabbit();
// Чи Ñе обâÑÐºÑ ÐºÐ»Ð°ÑÑ Rabbit?
alert( rabbit instanceof Rabbit ); // true
ÐÑн Ñакож пÑаÑÑÑ Ð· ÑÑнкÑÑÑми-конÑÑÑÑкÑоÑами:
// замÑÑÑÑ ÐºÐ»Ð°ÑÑ
function Rabbit() {}
alert( new Rabbit() instanceof Rabbit ); // true
â¦Ð з вбÑдованими клаÑами Ñк Array:
let arr = [1, 2, 3];
alert( arr instanceof Array ); // true
alert( arr instanceof Object ); // true
ÐÑÐ´Ñ Ð»Ð°Ñка, звеÑнÑÑÑ ÑвагÑ, Ñо arr Ñакож належиÑÑ Ð´Ð¾ клаÑÑ Object. Це ÑомÑ, Ñо ÐºÐ»Ð°Ñ Array пÑоÑоÑипно наÑлÑдÑÑÑÑÑÑ Ð²Ñд Object.
ÐазвиÑай, instanceof пеÑевÑÑÑÑ Ð»Ð°Ð½ÑÑжок пÑоÑоÑипÑв. Ðи Ñакож можемо задаÑи бÑдÑ-ÑÐºÑ ÑпеÑÑалÑÐ½Ñ Ð»Ð¾Ð³ÑÐºÑ Ð² ÑÑаÑиÑÐ½Ð¾Ð¼Ñ Ð¼ÐµÑÐ¾Ð´Ñ Symbol.hasInstance, Ñ Ð·Ð°Ð¼ÑниÑи звиÑÐ°Ð¹Ð½Ñ Ð¿Ð¾Ð²ÐµÐ´ÑнкÑ.
ÐлгоÑиÑм опеÑаÑÑÑ obj instanceof Class пÑаÑÑÑ Ð¿Ñиблизно наÑÑÑпним Ñином:
-
ЯкÑо Ñ ÑÑаÑиÑний меÑод
Symbol.hasInstance, ÑÐ¾Ð´Ñ Ð²Ñн пÑоÑÑо викликаÑÑÑÑÑ:Class[Symbol.hasInstance](obj). ÐÑн повинен повеÑнÑÑиtrueабоfalse, оÑÑ Ñ Ð²Ñе. ÐÑÑ Ñк ми можемо задаÑи поведÑнкÑinstanceof.ÐапÑиклад:
// задамо пеÑевÑÑÐºÑ instanceof Ñаким Ñином, // Ñо бÑдÑ-Ñо Ñз влаÑÑивÑÑÑÑ canEat - Ñе ÑваÑина class Animal { static [Symbol.hasInstance](obj) { if (obj.canEat) return true; } } let obj = { canEat: true }; alert(obj instanceof Animal); // true: Animal[Symbol.hasInstance](obj) бÑло викликано -
ÐÑлÑÑÑÑÑÑ ÐºÐ»Ð°ÑÑв не маÑÑÑ
Symbol.hasInstance. У ÑÑÐ¾Ð¼Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÑ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑÑÑÑÑÑ ÑÑандаÑÑна логÑка:obj instanceOf ClassпеÑевÑÑÑÑ ÑиClass.prototypeдоÑÑвнÑÑ Ð¾Ð´Ð½Ð¾Ð¼Ñ Ð· пÑоÑоÑипÑв Ñ Ð»Ð°Ð½ÑÑÐ¶ÐºÑ Ð¿ÑоÑоÑипÑвobj.ÐнÑими Ñловами, пÑоÑоÑипи поÑÑвнÑÑÑÑÑÑ Ð¾Ð´Ð¸Ð½ за одним:
obj.__proto__ === Class.prototype? obj.__proto__.__proto__ === Class.prototype? obj.__proto__.__proto__.__proto__ === Class.prototype? ... // ЯкÑо бÑдÑ-Ñке з Ð½Ð¸Ñ Ð±Ñде true, Ñо instanceof одÑÐ°Ð·Ñ Ð¶ веÑне true. // ЯкÑо ми доÑÑгли кÑнÑÑ Ð»Ð°Ð½ÑÑжка - повеÑÑаÑÑÑÑÑ falseУ Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ð¾Ð¼Ñ Ð²Ð¸Ñе пÑикладÑ
rabbit.__proto__ === Rabbit.prototype, ÑÐ¾Ð¼Ñ Ð¼Ð¸ Ð·Ð½Ð°Ñ Ð¾Ð´Ð¸Ð¼Ð¾ вÑдповÑÐ´Ñ Ð½ÐµÐ³Ð°Ð¹Ð½Ð¾.У ÑÐ°Ð·Ñ Ð½Ð°ÑлÑдÑÐ²Ð°Ð½Ð½Ñ Ð¼Ð¸ знайдемо Ñе, Ñо ÑÑкали, на дÑÑÐ³Ð¾Ð¼Ñ ÐºÑоÑÑ:
class Animal {} class Rabbit extends Animal {} let rabbit = new Rabbit(); alert(rabbit instanceof Animal); // true // rabbit.__proto__ === Animal.prototype (Ð½ÐµÐ¼Ð°Ñ Ð·Ð±ÑгÑ) // rabbit.__proto__.__proto__ === Animal.prototype (знайÑли!)
ÐÑÑ ÑлÑÑÑÑаÑÑÑ Ñого, Ñк опеÑаÑÑÑ rabbit instanceof Animal ÑÑÐºÐ°Ñ Animal.prototype Ñ Ð¿ÑоÑоÑипаÑ
:
Ðо ÑеÑÑ, Ñ Ñакож меÑод objA.isPrototypeOf(objB), Ñкий повеÑÑÐ°Ñ true ÑкÑо objA знаÑ
одиÑÑÑÑ Ð´ÐµÑÑ Ñ Ð»Ð°Ð½ÑÑÐ¶ÐºÑ Ð¿ÑоÑоÑипÑв Ð´Ð»Ñ objB. ÐÑже, пеÑевÑÑÐºÑ obj instanceof Class можна замÑниÑи на Class.prototype.isPrototypeOf(obj).
ЦÑкаво, але Ñам клаÑÑ Class не беÑе ÑÑаÑÑÑ Ð² пеÑевÑÑÑÑ! ÐÐ°Ñ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ Ð»Ð¸Ñе ланÑÑжок пÑоÑоÑипÑв Ñ Class.prototype.
Це може пÑизвеÑÑи до дивниÑ
наÑлÑдкÑв, коли влаÑÑивÑÑÑÑ prototype бÑло змÑнено пÑÑÐ»Ñ ÑÑвоÑÐµÐ½Ð½Ñ Ð¾Ð±âÑкÑа.
Як ÑÑÑ:
function Rabbit() {}
let rabbit = new Rabbit();
// ÐмÑнÑÑмо пÑоÑоÑип
Rabbit.prototype = {};
// ...Ñе бÑлÑÑе не rabbit!
alert( rabbit instanceof Rabbit ); // false
ÐонÑÑ: Object.prototype.toString Ð´Ð»Ñ Ð²Ð¸Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ ÑипÑ
Ðи вже знаÑмо, Ñо пÑоÑÑÑ Ð¾Ð±âÑкÑи пеÑеÑвоÑÑÑÑÑÑÑ Ð½Ð° ÑÑдки Ñк [object Object]:
let obj = {};
alert(obj); // [object Object]
alert(obj.toString()); // Ñеж Ñаме
Це ÑÑ
ÑеалÑзаÑÑÑ Ð¼ÐµÑода toString. Ðле Ñ Ð¿ÑиÑ
ована ÑÑнкÑÑÑ, Ñка ÑобиÑÑ Ð¼ÐµÑод toString набагаÑо поÑÑжнÑÑим. Ðи можемо викоÑиÑÑовÑваÑи його Ñк ÑозÑиÑений typeof Ñ Ð°Ð»ÑÑеÑнаÑÐ¸Ð²Ñ instanceof.
ÐвÑÑиÑÑ Ð´Ð¸Ð²Ð½Ð¾? ÐÑйÑно. ÐавайÑе ÑозбиÑаÑиÑÑ.
У ÑпеÑиÑÑкаÑÑÑ, вбÑдований меÑод toString можна виÑÑгнÑÑи з обâÑкÑа Ñа викликаÑи в конÑекÑÑÑ Ð±ÑдÑ-Ñкого ÑнÑого знаÑеннÑ. Ð ÑезÑлÑÑÐ°Ñ Ð·Ð°Ð»ÐµÐ¶Ð¸ÑÑ Ð²Ñд ÑÐ¸Ð¿Ñ ÑÑого знаÑеннÑ.
- ÐÐ»Ñ ÑиÑла Ñе бÑде
[object Number] - ÐÐ»Ñ Ð»Ð¾Ð³ÑÑного знаÑÐµÐ½Ð½Ñ Ñе бÑде
[object Boolean] - ÐлÑ
null:[object Null] - ÐлÑ
undefined:[object Undefined] - ÐÐ»Ñ Ð¼Ð°ÑивÑв:
[object Array] - â¦ÑоÑо.
ÐавайÑе пÑодемонÑÑÑÑÑмо:
// ÑкопÑÑÑмо меÑод toString Ñ Ð·Ð¼ÑÐ½Ð½Ñ Ð´Ð»Ñ Ð·ÑÑÑноÑÑÑ
let objectToString = Object.prototype.toString;
// Що Ñе за Ñип?
let arr = [];
alert( objectToString.call(arr) ); // [object Array]
ТÑÑ Ð¼Ð¸ викоÑиÑÑали call, Ñк опиÑано в ÑоздÑÐ»Ñ ÐекоÑаÑоÑи Ñа пеÑеадÑеÑаÑÑÑ Ð²Ð¸ÐºÐ»Ð¸ÐºÑ, call/apply, Ñоб викликаÑи ÑÑнкÑÑÑ objectToString з конÑекÑÑом this=arr.
ÐÑеÑÐµÐ´ÐµÐ½Ñ Ð°Ð»Ð³Ð¾ÑиÑм toString пеÑевÑÑÑÑ this Ñ Ð¿Ð¾Ð²ÐµÑÑÐ°Ñ Ð²ÑдповÑдний ÑезÑлÑÑаÑ. ÐÑлÑÑе пÑикладÑв:
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
ÐоведÑÐ½ÐºÑ Ð¼ÐµÑÐ¾Ð´Ñ Ð¾Ð±âÑкÑа toString можна налаÑÑÑваÑи за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ ÑпеÑÑалÑÐ½Ð¾Ñ Ð²Ð»Ð°ÑÑивоÑÑÑ Symbol.toStringTag.
ÐапÑиклад:
let user = {
[Symbol.toStringTag]: "User"
};
alert( {}.toString.call(user) ); // [object User]
ÐÐ»Ñ Ð±ÑлÑÑоÑÑÑ ÑпеÑиÑÑÑÐ½Ð¸Ñ Ð´Ð»Ñ ÑеÑедовиÑа обâÑкÑÑв Ñака влаÑÑивÑÑÑÑ Ñ. ÐÑÑ Ð´ÐµÑÐºÑ Ð¿Ñиклади Ð´Ð»Ñ Ð±ÑаÑзеÑа:
// toStringTag Ð´Ð»Ñ ÑпеÑиÑÑÑниÑ
Ð´Ð»Ñ ÑеÑедовиÑа обâÑкÑÑ Ñа клаÑÑ:
alert( window[Symbol.toStringTag]); // Window
alert( XMLHttpRequest.prototype[Symbol.toStringTag] ); // XMLHttpRequest
alert( {}.toString.call(window) ); // [object Window]
alert( {}.toString.call(new XMLHttpRequest()) ); // [object XMLHttpRequest]
Як баÑиÑе, ÑезÑлÑÑаÑом Ñ Ñаме Symbol.toStringTag (ÑкÑо ÑÑнÑÑ), загоÑнÑÑий Ñ [object ...].
ÐапÑикÑнÑÑ Ð¼Ð¸ маÑмо âtypeof на ÑÑеÑоÑÐ´Ð°Ñ â, Ñкий пÑаÑÑÑ Ð½Ðµ ÑÑлÑки Ð´Ð»Ñ Ð¿ÑимÑÑÐ¸Ð²Ð½Ð¸Ñ ÑипÑв Ð´Ð°Ð½Ð¸Ñ , але й Ð´Ð»Ñ Ð²Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð±âÑкÑÑв Ñ Ð½Ð°Ð²ÑÑÑ Ð¼Ð¾Ð¶Ðµ бÑÑи каÑÑомÑзований.
Ðи можемо викоÑиÑÑаÑи {}.toString.call замÑÑÑÑ instanceof Ð´Ð»Ñ Ð²Ð±ÑдованиÑ
обâÑкÑÑв, коли ми Ñ
оÑемо оÑÑимаÑи Ñип Ñ Ð²Ð¸Ð³Ð»ÑÐ´Ñ ÑÑдка, а не пÑоÑÑо Ð´Ð»Ñ Ð¿ÐµÑевÑÑки.
ÐÑдÑÑмки
ÐавайÑе пÑдÑÑмÑÑмо вÑÐ´Ð¾Ð¼Ñ Ð½Ð°Ð¼ меÑоди пеÑевÑÑки ÑипÑв:
| пÑаÑÑÑ Ð´Ð»Ñ | повеÑÑÐ°Ñ | |
|---|---|---|
typeof |
пÑимÑÑивÑв | ÑÑдок |
{}.toString |
пÑимÑÑивÑв, вбÑдованиÑ
обâÑкÑÑв, обâÑкÑÑв з Symbol.toStringTag |
ÑÑдок |
instanceof |
обâÑкÑÑв | true/false |
Як ми баÑимо, {}.toString ÑеÑ
нÑÑно Ñ âбÑлÑÑ Ð¿ÑоÑÑнÑÑимâ typeof.
РопеÑаÑÐ¾Ñ instanceof дÑйÑно ÑÑÑ, коли ми пÑаÑÑÑмо з ÑÑÑаÑÑ
ÑÑÑ ÐºÐ»Ð°ÑÑв Ñ Ñ
оÑемо пеÑевÑÑиÑи ÐºÐ»Ð°Ñ Ð· ÑÑаÑ
ÑваннÑм наÑлÑдÑваннÑ.
ÐоменÑаÑÑ
<code>, Ð´Ð»Ñ ÐºÑлÑÐºÐ¾Ñ ÑÑдкÑв â обгоÑнÑÑÑ ÑÑ Ñегом<pre>, Ð´Ð»Ñ Ð¿Ð¾Ð½Ð°Ð´ 10 ÑÑдкÑв â викоÑиÑÑовÑйÑе пÑÑоÑниÑÑ (plnkr, jsbin, codepenâ¦)