定義
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。