彻底了解instanceof的底层实现原理

一、作用:

①用于判断某个实例是否属于某构造函数

②在继承关系中用来判断一个实例是否属于它的父类型或者祖先类型的实例

说白了,只要右边变量的 prototype 在左边变量的原型链上即可。因此,instanceof 在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype,如果查找失败,则会返回 false

二、语法

[对象] instanceof [构造函数]

var obj = new Object()
obj instanceof Object // true

三、涉及的构造函数

基础类型:String、Number、Boolean、Undefined、Null、Symbol

复杂类型:Array,Object

其他类型: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__;  
    }
}

代码解释:

①L表示对象实例,R表示构造函数或者父类型实例

②取R的显式原型,取L的隐式原型

③循环遍历,进行判断②中的两个值是否相等,相等返回true,不相等继续查找L的原型链

五、未发生继承关系时

function Cat(name,age,type){
    this.name = name;
    this.age = age;
    this.type = type;
}
function Dog(name){
    this.name = name;
}
var cats = new Cat('有鱼',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”运行情况:

function instance_of(L, R) { // L即cats   R即Cat
    var O = R.prototype; //O为Cat.prototype
    L = L.__proto__;       // L为cats._proto_
    while (true) {    //执行循环
        if (L === null)   //不通过
            return false;   
        if (O === L)       //判断:Cat.prototype ===cats._proto_
                return true;  //如果等于就返回true,证明cats是Cat类型
        L = L.__proto__;   
    }
} 

再看一下“cats instanceof Object”运行情况:

function instance_of(L, R) { //L即cats  R即Object     
    var O = R.prototype;  //O为Object.prototype    
    L = L.__proto__;    // L为cats._proto_        
    while (true) {     //执行循环      
        if (L === null)   //不通过  
            return false;      
        if (O === L)   // 此时判断Object.prototype === cats._proto_ 显然不成立
             return true;                         
         L = L.__proto__;   //遍历cats的原型链,即此时L为 cats._proto_ ._proto_,
                          //即Cat.prototype._proto_指向的对象,
                         //接着执行循环,
                         //到Object .prototype === cats._proto_ ._proto_
                         //成立,返回true
    }
}

六、产生继承关系时

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();  // 这里改变了原型指向,实现继承
var yd = new YingDuan("有鱼",2,"金渐层","男"); //创建了英短对象yd
console.log(yd instanceof YingDuan);    // true
console.log(yd instanceof Cat);    // true
console.log(yd instanceof Object);    // true

先看一下“yd instanceof YingDuan”运行情况:

function instance_of(L, R) { //L即yd  R即YingDuan
   var O = R.prototype;  //O为YingDuan.prototype,现在指向了cat
    L = L.__proto__;    //L为yd._proto_,也随着prototype的改变而指向了cat
    while (true) {    //执行循环
        if (L === null)  //不通过
            return false;   
        if (O === L)    //判断是否 YingDuan.prototype ===yd._proto_ 
            return true;  //此时,两方都指Cat的实例对象cat,所以true
        L = L.__proto__;       
    }
} 

再看一下“yd instanceof Cat”运行情况,即如何判断yd继承了Cat:

function instance_of(L, R) { // L即yd  R即Cat  
   var O = R.prototype; // O为Cat.prototype    
    L = L.__proto__;   //L为yd._proto_,现在指向的是cat实例对象
    while (true) {   // 执行循环   
       if (L === null)   //不通过    
           return false;         
       if (O === L)    //判断是否 Cat.prototype === yd._proto_   
            return true;   //此时,yd._proto_ 指向cat实例对象,并不满足
        L = L.__proto__;  //令L=  yd._proto_._proto_,执行循环
   }                      //yd._proto_ ._proto_,指的就是Cat.prototype,所以也返回true
}                         //这就证明了yd继承了Cat

yd instanceof Object也是同理的,这里暂不赘述。

七、注意问题

instanceof 用于判断对象类型,但以下情况的结果都为false,请注意。

console.log(Number instanceof Number)  // false
console.log(String instanceof String)  // false
console.log(Fun instanceof Fun)        // false,这里Fun指的是函数
console.log(null instanceof Object)   // false,null不具有任何对象的特性,也没有__proto__属性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值