a instanceof b
总是一样吗b.prototype.isPrototypeOf(a)
?
不,a instanceof b
不会总是表现得与b.prototype.isPrototypeOf(a)
.
CMS 的回答指出,它们的本质不同(一个是运算符,另一个是对象上可用的内置方法Object.prototype
)。这是正确的,但是也有一些特殊情况a instanceof b
会导致一段TypeError
时间b.prototype.isPrototypeOf(a)
会正常工作,反之亦然。
差异#1
的右侧instanceof
应该是构造函数。
如果b
不是函数:
const b = {
prototype: {}
};
const a = Object.create( b.prototype );
console.log( b.prototype.isPrototypeOf(a) ); // true
console.log( a instanceof b ); // TypeError: Right-hand side of 'instanceof' is not callable
差异#2
使用时b.prototype.isPrototypeOf(a)
,b.prototype
应继承自Object.prototype
:
如果b.prototype
没有访问Object.prototype.isPrototypeOf()
方法:
b.prototype.isPrototypeOf(a)
将导致一个TypeError
.
a instanceof b
会工作得很好。
function B() {};
B.prototype = Object.create( null );
const a = new B();
console.log( a instanceof B ); // true
console.log( B.prototype.isPrototypeOf(a) ) // TypeError: B.prototype.isPrototypeOf is not a function
差异#3
如果 的右侧instanceof
是绑定函数,则将其等同于其目标函数。
如果 b 是绑定函数:
a instanceof b
会工作得很好。
b.prototype.isPrototypeOf(a)
将导致TypeError
(绑定函数没有prototype
属性)。
function B() {};
const BoundB = B.bind( null );
const a = new B();
console.log( a instanceof BoundB ); // true
console.log( BoundB.prototype.isPrototypeOf(a) ) // TypeError: Cannot read property 'isPrototypeOf' of undefined
结论
- 如果您正在处理通过 建立的原型继承
Object.create()
,而不使用构造函数,则您可能应该使用该Object.prototype.isPrototypeOf()
方法(实际上, 的用例instanceof
受到更多限制,因为它instanceof
期望其右侧参数是构造函数)。
- 如果您正在处理构造函数,则使用
instanceof
运算符会稍微安全一些(您将能够涵盖绑定函数以及Object.prototype
不在原型链中的情况Constructor.prototype
)。