美文网首页js
js instanceof 与 isPrototypeOf 的区

js instanceof 与 isPrototypeOf 的区

作者: world_7735 | 来源:发表于2018-10-30 13:33 被阅读37次

    定义

    B instanceof A:

    A构造函数的prototype对象是否在B的原型链上
    

    A.isPrototypeOf(B):

    A对象是否在B的原型链上
    

    定义上的区别比较难以理解,先从一个例子开始。

    实例

    class A{}
    class B extends A{}
    let b = new B();
    

    一个很简单的继承,首先弄清楚这两个类之间的关系

    B.__proto__ ===  A //true
    B.prototype.__proto__==A.prototype //true
    b.__proto__ === B.prototype //true
    

    为什么是这样呢
    首先类的继承是按下面方式实现的

    class A {
    }
    
    class B {
    }
    
    // B的实例继承A的实例
    Object.setPrototypeOf(B.prototype, A.prototype);
    const b = new B();
    
    // B的实例继承A的静态属性
    Object.setPrototypeOf(B, A);
    const b = new B();
    

    我们知道setPrototypeOf方法是

    Object.setPrototypeOf = function (obj, proto) {
      obj.__proto__ = proto;
      return obj;
    }
    

    所以得出前两个表达式
    而new操作是按如下方式实现的

    var b = new Object();
    b.__proto__ = B.prototype; 
    B.call(b);
    

    所有得到第三个表达式

    接下来看看instanceof和isPrototypeOf

    A.isPrototypeOf(B);//true
    A.isPrototypeOf(b);//false
    b instanceof B;//true
    b instanceof A;//true
    B instanceof A;//false
    

    再把刚才的关系提一遍

    B.__proto__ ===  A //true
    B.prototype.__proto__=A.prototype //true
    b.__proto__ === B.prototype //true
    

    回头看定义就清晰很多了
    A对象在B的原型链上,不在b的原型链上,所以

    A.isPrototypeOf(B);//true
    A.isPrototypeOf(b);//false
    

    A,B的prototype在b的原型链上而不在B的原型链上,所以

    b instanceof B;//true
    b instanceof A;//true
    B instanceof A;//false
    

    总结

    也就是说Y instanceof X判断是的是X的prototype是否在Y的原型链上,而我们知道实例的原型链(proto)指向的就是其构造函数的prototype,即Y instanceof X判断Y是否是X的一个实例(若Y是X的实例,那他也是X的父类的实例)
    而X.isPrototypeOf(Y)判断的是X对象是否在Y的原型链上,同样Y继承X的关系是X对象在Y对象的原型链上,即X.isPrototypeOf(Y)判断X是否继承至Y。

    相关文章

      网友评论

        本文标题:js instanceof 与 isPrototypeOf 的区

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