[FE] instanceof自定义Error

在生产环境中使用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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容