出于某种原因,在下面的代码段中,构造函数委托似乎不起作用:

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

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

运行该命令得到的消息是:"。有什么想法,为什么,或者是否有更好的方法来创建一个新的错误子类?是否有一个问题,应用到本机错误构造函数,我不知道?


当前回答

这在Cesium DeveloperError中很好地实现了:

文档 源

它的简化形式是:

var NotImplementedError = function(message) {
    this.name = 'NotImplementedError';
    this.message = message;
    this.stack = (new Error()).stack;
}

// Later on...

throw new NotImplementedError();

其他回答

function InvalidValueError(value, type) {
    this.message = "Expected `" + type.name + "`: " + value;
    var error = new Error(this.message);
    this.stack = error.stack;
}
InvalidValueError.prototype = new Error();
InvalidValueError.prototype.name = InvalidValueError.name;
InvalidValueError.prototype.constructor = InvalidValueError;

构造函数需要类似于工厂方法,并返回您想要的内容。如果你需要额外的方法/属性,你可以在返回之前将它们添加到对象中。

function NotImplementedError(message) { return new Error("Not implemented", message); }

x = new NotImplementedError();

不过我不明白你为什么要这么做。为什么不直接使用new Error…? 自定义异常在JavaScript(或任何非类型化语言)中并没有真正添加太多内容。

class NotImplementedError extends Error {
  constructor(message) {
    super(message);
    this.message = message;
  }
}
NotImplementedError.prototype.name = 'NotImplementedError';
module.exports = NotImplementedError;

and

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);
}

它只是这个答案的一个类表示。

输出

NotImplementedError: NotImplementedError message
  ...stacktrace
ex1 instanceof NotImplementedError = true
ex1 instanceof Error = true
ex1.name = NotImplementedError
ex1.message = NotImplementedError message

更新代码,将原型分配给Error。Prototype和instanceof以及你的断言工作。

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

不过,我会抛出你自己的对象并检查name属性。

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

根据评论进行编辑

在看了评论并试图记住为什么我将prototype分配给Error后。而不是像Nicholas Zakas在他的文章中所做的new Error(),我用下面的代码创建了一个jsFiddle:

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

这证实了我遇到的“问题”是错误的堆栈属性是创建new error()的行号,而不是抛出e发生的地方。然而,这可能比NotImplementedError.prototype.name = "NotImplementedError"行影响Error对象的副作用要好。

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

尝试为用户定义的错误类型的每个实例创建一个新的原型对象。它允许instanceof检查像往常一样运行,并且在Firefox和V8 (Chome, nodejs)中正确报告类型和消息。

function NotImplementedError(message){
    if(NotImplementedError.innercall===undefined){
        NotImplementedError.innercall = true;
        NotImplementedError.prototype = new Error(message);
        NotImplementedError.prototype.name = "NotImplementedError";
        NotImplementedError.prototype.constructor = NotImplementedError;

        return new NotImplementedError(message);
    }
    delete NotImplementedError.innercall;
}

注意,一个额外的条目将在正确的堆栈之前。