美文网首页
彻底了解instanceof的底层实现原理

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

作者: 有鱼是只猫 | 来源:发表于2020-02-06 23:01 被阅读0次

    一、作用

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

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

    说白了,只要右边变量的 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__属性

    相关文章

      网友评论

          本文标题:彻底了解instanceof的底层实现原理

          本文链接:https://www.haomeiwen.com/subject/xydpxhtx.html