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
- 有谁知道在扩展 Error 时是否有办法覆盖构造函数名称?
- 此外,为什么我不能在 CustomError 错误中声明和调用方法 class?
编辑
根据@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。
使用:
node v8.8.1
babel-node v6.26.0 w/ "es2015" 和 "stage-0" 预设
谢谢!
在这个简单的例子中似乎工作得很好:
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
我在我的应用程序中创建了一些自定义错误,我想稍后使用构造函数名称检查它们。问题是,当我在 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
- 有谁知道在扩展 Error 时是否有办法覆盖构造函数名称?
- 此外,为什么我不能在 CustomError 错误中声明和调用方法 class?
编辑
根据@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。
使用:
node v8.8.1
babel-node v6.26.0 w/ "es2015" 和 "stage-0" 预设
谢谢!
在这个简单的例子中似乎工作得很好:
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 returnsthis.constructor.name