使用ES6 class
语法,我想知道为什么当有多个继承链时,instanceof
运算符不适用于继承链?
(可选阅读)
instanceof
运营商如何运作?在
obj instanceof Constructor
中,instanceof
运算符会检查'prototype'
函数的Constructor
属性是否存在于{em> prototype 链中{ {1}}。如果存在,请返回obj
。否则,true
。
在以下代码段中,false
继承自BTError
( 1。 ),Error
延伸自{{1} ( 3。 )
但正如我们可以从( 4。 )中看到的那样,SomeError
运算符为BTError
生成了instanceof
,我的理解应该是false
。
new SomeError() instanceof BTError
有什么非平凡的我无法理解,或者true
操作员只是表现怪异的?
答案 0 :(得分:5)
专注于你的例子的最后一部分
您正在使用BabelJS转换此代码以使其兼容
class BTError extends Error {}
class SomeError extends BTError {}
class SpecificError extends SomeError {}
console.log('6.', new SpecificError() instanceof Error);
console.log('7.', new SpecificError() instanceof BTError);
console.log('8.', new SpecificError() instanceof SomeError);
这是上面代码的转换版本
'use strict';
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _possibleConstructorReturn(self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
var BTError = function(_Error) {
_inherits(BTError, _Error);
function BTError() {
_classCallCheck(this, BTError);
return _possibleConstructorReturn(this, (BTError.__proto__ || Object.getPrototypeOf(BTError)).apply(this, arguments));
}
return BTError;
}(Error);
var SomeError = function(_BTError) {
_inherits(SomeError, _BTError);
function SomeError() {
_classCallCheck(this, SomeError);
return _possibleConstructorReturn(this, (SomeError.__proto__ || Object.getPrototypeOf(SomeError)).apply(this, arguments));
}
return SomeError;
}(BTError);
var SpecificError = function(_SomeError) {
_inherits(SpecificError, _SomeError);
function SpecificError() {
_classCallCheck(this, SpecificError);
return _possibleConstructorReturn(this, (SpecificError.__proto__ || Object.getPrototypeOf(SpecificError)).apply(this, arguments));
}
return SpecificError;
}(SomeError);
console.log('6.', new SpecificError() instanceof Error); // 6. true
console.log('7.', new SpecificError() instanceof BTError); // 7. false
console.log('8.', new SpecificError() instanceof SomeError); // 8. false
我认为问题源于_inherit
方法,它直接分配给subClass.prototype
而不是superClass.prototype
,而是通过合并它和另一组默认属性创建的对象。
使用这个原型链,继承可以工作,但是instanceof运算符无法通过引用传递它,因此您可以false
得到true
。
显然,根据this bug report,这是已知和预期的行为(即限制),可能的解决方法是使用babel-plugin-transform-builtin-extend
答案 1 :(得分:2)
使用TypeScript遇到此问题。通过在超级调用之后在类构造函数中添加以下内容来解决此问题:
Object.setPrototypeOf(this, YOUR_CLASS_HERE.prototype);
不确定是否对您有帮助。
答案 2 :(得分:1)
在我的情况下,instanceof
在将编译目标设置为“ es5”的情况下不起作用。更改为“ es6”后,将产生正确的结果。