如何在 JavaScript 中创建自定义错误?

2022-08-30 00:25:20

由于某种原因,构造函数委派在以下代码段中似乎不起作用:

function NotImplementedError() { 
  Error.apply(this, arguments); 
}
NotImplementedError.prototype = new Error();

var nie = new NotImplementedError("some message");
console.log("The message is: '"+nie.message+"'")

运行此项可得到 .关于为什么,或者是否有更好的方法来创建新的子类的任何想法?对于我不知道的本机构造函数,是否存在问题?The message is: ''ErrorapplyError


答案 1

更新代码以将原型分配给 Error.prototype 以及实例和断言工作。

function NotImplementedError(message = "") {
    this.name = "NotImplementedError";
    this.message = message;
}
NotImplementedError.prototype = Error.prototype;

但是,我会抛出你自己的对象,只检查name属性。

throw {name : "NotImplementedError", message : "too lazy to implement"}; 

根据注释进行编辑

在查看了注释并试图记住为什么我会分配原型而不是像Nicholas Zakas在他的文章中所做的那样,我用下面的代码创建了一个jsFiddleError.prototypenew Error()

function NotImplementedError(message = "") {
  this.name = "NotImplementedError";
  this.message = message;
}
NotImplementedError.prototype = Error.prototype;

function NotImplementedError2(message = "") {
  this.message = message;
}
NotImplementedError2.prototype = new Error();

try {
  var e = new NotImplementedError("NotImplementedError message");
  throw e;
} catch (ex1) {
  console.log(ex1.stack);
  console.log("ex1 instanceof NotImplementedError = " + (ex1 instanceof NotImplementedError));
  console.log("ex1 instanceof Error = " + (ex1 instanceof Error));
  console.log("ex1.name = " + ex1.name);
  console.log("ex1.message = " + ex1.message);
}

try {
  var e = new NotImplementedError2("NotImplementedError2 message");
  throw e;
} catch (ex1) {
  console.log(ex1.stack);
  console.log("ex1 instanceof NotImplementedError2 = " + (ex1 instanceof NotImplementedError2));
  console.log("ex1 instanceof Error = " + (ex1 instanceof Error));
  console.log("ex1.name = " + ex1.name);
  console.log("ex1.message = " + ex1.message);
}

控制台输出是这样的。

undefined
ex1 instanceof NotImplementedError = true
ex1 instanceof Error = true
ex1.name = NotImplementedError
ex1.message = NotImplementedError message
Error
    at window.onload (http://fiddle.jshell.net/MwMEJ/show/:29:34)
ex1 instanceof NotImplementedError2 = true
ex1 instanceof Error = true
ex1.name = Error
ex1.message = NotImplementedError2 message

这证实了我遇到的“问题”是错误的堆栈属性是创建行号的位置,而不是发生的位置。但是,这可能比具有影响 Error 对象的行的副作用更好。new Error()throw eNotImplementedError.prototype.name = "NotImplementedError"

另外,请注意,当我没有显式设置时,它等于“Error”。但是,正如评论中提到的,因为该版本将原型设置为,所以我可以设置并OK。NotImplementedError2.namenew Error()NotImplementedError2.prototype.name = "NotImplementedError2"


答案 2

在ES2015中,您可以使用干净利落地执行此操作:class

class NotImplemented extends Error {
  constructor(message = "", ...args) {
    super(message, ...args);
    this.message = message + " has not yet been implemented.";
  }
}

这不会修改全局原型,允许您自定义 、 和其他属性,并正确捕获堆栈。它也非常可读。Errormessagename

当然,您可能需要使用一种工具,例如您的代码将在较旧的浏览器上运行。babel