一、作用
①用于判斷某個(gè)實(shí)例是否屬于某構(gòu)造函數(shù)
②在繼承關(guān)系中用來(lái)判斷一個(gè)實(shí)例是否屬于它的父類(lèi)型或者祖先類(lèi)型的實(shí)例
說(shuō)白了,只要右邊變量的 prototype 在左邊變量的原型鏈上即可。因此,instanceof 在查找的過(guò)程中會(huì)遍歷左邊變量的原型鏈,直到找到右邊變量的 prototype,如果查找失敗,則會(huì)返回 false
二、語(yǔ)法
[對(duì)象] instanceof [構(gòu)造函數(shù)]
如:
var obj = new Object()
obj instanceof Object // true
三、涉及的構(gòu)造函數(shù)
基礎(chǔ)類(lèi)型:String、Number、Boolean、Undefined、Null、Symbol
復(fù)雜類(lèi)型:Array,Object
其他類(lèi)型:Function、RegExp、Date
四、底層原理
function instance_of(L, R) {
? ? var O = R.prototype;
? ? L = L.__proto__;
? ? while (true) {? ?
? ? ? ? if (L === null)? ? ?
? ? ? ? ? ? return false;?
? ? ? ? if (O === L)
? ? ? ? ? ? return true;?
? ? ? ? L = L.__proto__;?
? ? }
}
代碼解釋?zhuān)?/p>
①L表示對(duì)象實(shí)例,R表示構(gòu)造函數(shù)或者父類(lèi)型實(shí)例
②取R的顯式原型,取L的隱式原型
③循環(huán)遍歷,進(jìn)行判斷②中的兩個(gè)值是否相等,相等返回true,不相等繼續(xù)查找L的原型鏈
五、未發(fā)生繼承關(guān)系時(shí)
function Cat(name,age,type){
? ? this.name = name;
? ? this.age = age;
? ? this.type = type;
}
function Dog(name){
? ? this.name = name;
}
var cats = new Cat('有魚(yú)',2,'英短');
var dogs = new Dog('哈士奇');
console.log(cats instanceof Cat);? // true
console.log(dogs instanceof Dog);? // true
console.log(cats instanceof Object);? // true
console.log(dogs instanceof Object);? // true
先看一下“cats instanceof Cat”運(yùn)行情況:
function instance_of(L, R) { // L即cats? R即Cat
? ? var O = R.prototype; //O為Cat.prototype
? ? L = L.__proto__;? ? ? // L為cats._proto_
? ? while (true) {? ? //執(zhí)行循環(huán)
? ? ? ? if (L === null)? //不通過(guò)
? ? ? ? ? ? return false;?
? ? ? ? if (O === L)? ? ? //判斷:Cat.prototype ===cats._proto_
? ? ? ? ? ? ? ? return true;? //如果等于就返回true,證明cats是Cat類(lèi)型
? ? ? ? L = L.__proto__;?
? ? }
}
再看一下“cats instanceof Object”運(yùn)行情況:
function instance_of(L, R) { //L即cats? R即Object? ?
? ? var O = R.prototype;? //O為Object.prototype? ?
? ? L = L.__proto__;? ? // L為cats._proto_? ? ? ?
? ? while (true) {? ? //執(zhí)行循環(huán)? ? ?
? ? ? ? if (L === null)? //不通過(guò)?
? ? ? ? ? ? return false;? ? ?
? ? ? ? if (O === L)? // 此時(shí)判斷Object.prototype === cats._proto_ 顯然不成立
? ? ? ? ? ? return true;? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? L = L.__proto__;? //遍歷cats的原型鏈,即此時(shí)L為 cats._proto_ ._proto_,
? ? ? ? ? ? ? ? ? ? ? ? ? //即Cat.prototype._proto_指向的對(duì)象,
? ? ? ? ? ? ? ? ? ? ? ? //接著執(zhí)行循環(huán),
? ? ? ? ? ? ? ? ? ? ? ? //到Object .prototype === cats._proto_ ._proto_
? ? ? ? ? ? ? ? ? ? ? ? //成立,返回true
? ? }
}
六、產(chǎn)生繼承關(guān)系時(shí)
function Cat(name,age,type){
? ? this.name = name;
? ? this.age = age;
? ? this.type = type;
}
function YingDuan(name,age,type,sex){
? ? Cat.call(this,name,age,type);?
? ? this.sex = sex;
}
YingDuan.prototype = new Cat();? // 這里改變了原型指向,實(shí)現(xiàn)繼承
var yd = new YingDuan("有魚(yú)",2,"金漸層","男"); //創(chuàng)建了英短對(duì)象yd
console.log(yd instanceof YingDuan);? ? // true
console.log(yd instanceof Cat);? ? // true
console.log(yd instanceof Object);? ? // true
先看一下“yd instanceof YingDuan”運(yùn)行情況:
function instance_of(L, R) { //L即yd? R即YingDuan
? var O = R.prototype;? //O為YingDuan.prototype,現(xiàn)在指向了cat
? ? L = L.__proto__;? ? //L為yd._proto_,也隨著prototype的改變而指向了cat
? ? while (true) {? ? //執(zhí)行循環(huán)
? ? ? ? if (L === null)? //不通過(guò)
? ? ? ? ? ? return false;?
? ? ? ? if (O === L)? ? //判斷是否 YingDuan.prototype ===yd._proto_
? ? ? ? ? ? return true;? //此時(shí),兩方都指Cat的實(shí)例對(duì)象cat,所以true
? ? ? ? L = L.__proto__;? ? ?
? ? }
}
再看一下“yd instanceof Cat”運(yùn)行情況,即如何判斷yd繼承了Cat:
function instance_of(L, R) { // L即yd? R即Cat?
? var O = R.prototype; // O為Cat.prototype? ?
? ? L = L.__proto__;? //L為yd._proto_,現(xiàn)在指向的是cat實(shí)例對(duì)象
? ? while (true) {? // 執(zhí)行循環(huán)?
? ? ? if (L === null)? //不通過(guò)? ?
? ? ? ? ? return false;? ? ? ?
? ? ? if (O === L)? ? //判斷是否 Cat.prototype === yd._proto_?
? ? ? ? ? ? return true;? //此時(shí),yd._proto_ 指向cat實(shí)例對(duì)象,并不滿足
? ? ? ? L = L.__proto__;? //令L=? yd._proto_._proto_,執(zhí)行循環(huán)
? }? ? ? ? ? ? ? ? ? ? ? //yd._proto_ ._proto_,指的就是Cat.prototype,所以也返回true
}? ? ? ? ? ? ? ? ? ? ? ? //這就證明了yd繼承了Cat
yd instanceof Object也是同理的,這里暫不贅述。
七、注意問(wèn)題
instanceof 用于判斷對(duì)象類(lèi)型,但以下情況的結(jié)果都為false,請(qǐng)注意
console.log(Number instanceof Number)? // false
console.log(String instanceof String)? // false
console.log(Fun instanceof Fun)? ? ? ? // false,這里Fun指的是函數(shù)
console.log(null instanceof Object)? // false,null不具有任何對(duì)象的特性,也沒(méi)有__proto__屬性