彻底了解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__属性

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些阅读 6,179评论 0 2
  • 前言 如果你要开发一个复杂的产品,那么肯定少不了使用面向对象机制,当然也避不开 Javascript 里面的继承,...
    lifeColder阅读 4,093评论 0 1
  • 如何控制alert中的换行?\n alert(“p\np”); 请编写一个JavaScript函数 parseQu...
    heyunqiang99阅读 4,744评论 0 6
  • 绿蚁新醅酒、红泥小火炉,晚来天欲雪,能饮一杯无。看到阴沉的天,就冒出了这首诗,又是一年冬。 (一)冬日的吃 冬日,...
    沙枣花zyh阅读 1,868评论 0 2
  • 刚毕业的时候觉得租房子也不错,没有想买房子的想法。 过了25岁,到了奔三的年龄,就越来越渴望有个家,属于自己的房子...
    茶包与橙汁阅读 1,616评论 1 0

友情链接更多精彩内容