完全了解instanceof的底层实现原理

1、做用
①用于判断某个实例是否属于某构造函数
②在继承关系中用来判断一个实例是否属于它的父类型或者祖先类型的实例
说白了,只要右边变量的 prototype 在左边变量的原型链上便可。所以,instanceof 在查找的过程当中会遍历左边变量的原型链,直到找到右边变量的 prototype,若是查找失败,则会返回 false函数

2、语法
[对象] instanceof [构造函数]
如:this

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

3、涉及的构造函数
基础类型:String、Number、Boolean、Undefined、Null、Symbol
复杂类型:Array,Object
其余类型:Function、RegExp、Dateprototype

4、底层原理code

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的原型链对象

5、未发生继承关系时继承

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
    }
}

6、产生继承关系时io

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”运行状况:console

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也是同理的,这里暂不赘述。

7、注意问题
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__属性
相关文章
相关标签/搜索