在生产环境中使用Babel,发现instanceof
在自定义Error
的情况出错了,
用例如下:
// User defined base class
class Base { }
class Sub extends Base { }
let sub = new Sub;
console.assert(sub instanceof Sub); //pass
console.assert(sub instanceof Base);
// Builtin base class, such as Error
class UserDefinedError extends Error { }
let e = new UserDefinedError;
console.assert(e instanceof UserDefinedError); //failed
console.assert(e instanceof Error);
这里有篇文章提到了这一点:
Why doesn't instanceof work on instances of Error subclasses under babel-node?
Extending builtin types like Array and Error and such has never been supported in Babel.
It is perfectly valid in a real ES6 environment, but there are requirements to make it work that are very difficult to transpile in a way that is compatible with older browsers.
方案1:
function ExtendableBuiltin(cls) {
function ExtendableBuiltin() {
cls.apply(this, arguments);
}
ExtendableBuiltin.prototype = Object.create(cls.prototype);
Object.setPrototypeOf(ExtendableBuiltin, cls);
return ExtendableBuiltin;
}
class UserDefinedError extends ExtendableBuiltin(Error) { }
let sub = new UserDefinedError;
console.assert(sub instanceof UserDefinedError); //pass
参考:
Extending builtins like Error and Array doesn't work in 6.x
方案2:
function MyError(message) {
this.name = 'MyError';
this.message = message || 'Default Message';
this.stack = (new Error()).stack;
}
MyError.prototype = Object.create(Error.prototype);
MyError.prototype.constructor = MyError;
try {
throw new MyError();
} catch (e) {
console.log(e.name); // 'MyError'
console.log(e.message); // 'Default Message'
}
try {
throw new MyError('custom message');
} catch (e) {
console.log(e.name); // 'MyError'
console.log(e.message); // 'custom message'
}
参考:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error