【问题标题】:JavaScript - How to get child class name when extending ErrorJavaScript - 扩展错误时如何获取子类名称
【发布时间】:2018-07-03 15:51:36
【问题描述】:

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

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

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

  • 有谁知道在扩展 Error 时是否可以覆盖构造函数名称?
  • 另外,为什么我不能在我的 CustomError 错误类中声明和调用方法?

编辑

根据@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 语句而不必等待 node v9.4 LTS。

使用:

  • 节点 v8.8.1

  • babel-node v6.26.0 w/“es2015”和“stage-0”预设

谢谢!

【问题讨论】:

  • 它在我的工作正常

标签: javascript node.js class constructor extend


【解决方案1】:

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

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() 示例不起作用这一事实似乎也表明正在发生一些时髦的事情。您发布的示例看起来不错。仔细检查您尝试运行的代码实际上是否与它们匹配。

【讨论】:

  • 是的,我确实在使用 babel 作为转译器。我正在使用nodejs v6.9.1,也许我会尝试切换到v7.1+并在没有babel的情况下运行它,看看是否有效
  • Node.js 6.* 远远落后。当前的 LTS 是 8.*,并且 9.* 可用。可能你有一个旧版本的 babel,它有一个自修复的错误或其他东西。
【解决方案2】:

一个简单的解决方案如下

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' 的更多信息,您可以查看https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get

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

【讨论】:

    【解决方案3】:

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

    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"
    

    或者你可以简单地在你的基类中添加一个name() getter 来返回this.constructor.name

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-16
      • 1970-01-01
      • 1970-01-01
      • 2012-03-23
      相关资源
      最近更新 更多