JavaScript - 如何在扩展错误时获取 child class 名称

JavaScript - How to get child class name when extending Error

我在我的应用程序中创建了一些自定义错误,我想稍后使用构造函数名称检查它们。问题是,当我在 classes 中扩展错误时,constructor.name 始终是 "Error",而不是我实际赋予它的名称。

我正在做一些测试并注意到错误 class 会发生这种情况,但我创建的任何其他自定义 class 不会发生这种情况。 例如:

class CustomClass {
  constructor(msg) {}
}

class OtherClass extends CustomClass {
   constructor(msg) {
     super(msg);
}

class CustomError extends Error {
  constructor(msg) {
    super(msg);
  }
}

const e = new CustomError("There was an error");
const otherClass = new OtherClass("This is a class");

console.log(otherClass.constructor.name); // "OtherClass" <- ok!
console.log(e.constructor.name); // "Error" <- not ok! expected "CustomError"

有人知道为什么会这样吗?

我想我可以做类似的事情:

class CustomError extends Error {
  constructor(msg) {
    super(msg);
  }

  getName() {
    return "CustomError";
  }
}

const e = new CustomError("There was an error");
if(e.getName() == "CustomError") {
  // do stuff
}

但后来我得到:TypeError: e.getName is not a function

编辑

根据@samanime 的建议,我将我的节点版本更新到 8.8.1 并找到了部分解决方案。

稍微更改语法我得到:

const FileSystemException = module.exports = class FileSystemException extends Error {
    constructor(msg) {
        super(msg);
    }

    getName() {
        return "FileSystemException";
    }
}

const e = new FileSystemException("There was an error");

// Running node app.js
console.log(e.constructor.name); // "FileSystemException"
console.log(e.getName()); // "FileSystemException"

// Running babel-node app.js
console.log(e.constructor.name); // "Error"
console.log(e.getName()); // "TypeError: e.getName is not a function"

不过,如果有人可以让它与 babel 一起工作,那就太棒了,这样我就可以使用 import/export 语句而无需等待节点 v9.4 LTS。

使用:

谢谢!

在这个简单的例子中似乎工作得很好:

class CustomError extends Error {
 constructor(msg) { 
   super(msg);
 }
}

const error = new CustomError()
console.log(error.constructor.name);
console.log(error instanceof CustomError);
console.log(error instanceof Error);

即 运行 原生 class 支持(在 Chrome 中)。

这可能不是您语法的问题,而是您的编译器的问题。您可能想深入了解转译代码本身,看看它是否对 Error 做了一些与正常 类.

没有的特殊事情

您的 getName() 示例不起作用的事实似乎也表明发生了一些奇怪的事情。您发布的示例看起来不错。仔细检查您尝试 运行 的代码是否与它们匹配。

一个简单的解决方案如下

class CustomError extends Error {
  constructor(msg) {
    super(msg);
  }
  
  get name(){
    return 'CustomError'
  }
}

const e = new CustomError("There was an error");

console.log(e.constructor.name); // "CustomError"
console.log(e.name); // "CustomError"

这还将更改堆栈跟踪中的错误名称,因此当您抛出自定义错误对象时,您将看到: CustomError: some random stack trace

而不是: Error: some random stack trace

关于在js中使用'get'的更多信息classes/objects,可以看看https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get

希望我参加聚会还不算太晚,希望对您有所帮助。

要正确设置 error.name,您可以为所有自定义错误创建一个基础 class。

class MyAbstractError extends Error {
    constructor(message) { 
       super(message);
       this.name = this.constructor.name;
    }
}

class NotFoundError extends MyAbstractError {}
class BadParameterError extends MyAbstractError {}

console.log( (new BadParameter("x")).name) // => "BadParameter"
console.log( (new NotFoundError ("x")).name) // => "NotFoundError"

Or you can simply add a name() getter in your base class that returns this.constructor.name