js

js instanceof 与 isPrototypeOf 的区

2018-10-30  本文已影响37人  world_7735

定义

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。

上一篇下一篇

猜你喜欢

热点阅读