由于某些原因,构造函数委托在下面的代码片段中看起来不起作用:
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: ''。有什么想法可以解释为什么,或者有没有更好的方法来创建一个新的Error子类?apply到本机Error构造函数有没有我不知道的问题?
发布于 2009-05-16 03:51:53
更新您的代码以将您的原型分配给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.prototype而不是Nicholas Zakas在他的article中所做的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()的行号,而不是throw e发生的位置。然而,这可能比具有影响错误对象的NotImplementedError.prototype.name = "NotImplementedError"线的副作用要好。
另外,请注意对于NotImplementedError2,当我没有显式设置错误时,它等于“.name”。但是,正如注释中所提到的,因为该版本将prototype设置为new Error(),所以我可以设置为NotImplementedError2.prototype.name = "NotImplementedError2",这样就可以了。
发布于 2013-07-27 05:12:06
上面所有的答案都是非常糟糕的--真的。即使是有107个ups的那个!真正的答案就在这里:
Inheriting from the Error object - where is the message property?
TL;DR:
没有设置message的原因是,Error是一个返回新错误对象的函数,并且不以任何方式操作this。
B.正确的方法是从构造函数返回应用的结果,并以通常复杂的javascripty方式设置原型:
function MyError() {
var temp = Error.apply(this, arguments);
temp.name = this.name = 'MyError';
this.message = temp.message;
if(Object.defineProperty) {
// getter for more optimizy goodness
/*this.stack = */Object.defineProperty(this, 'stack', {
get: function() {
return temp.stack
},
configurable: true // so you can change it if you want
})
} else {
this.stack = temp.stack
}
}
//inherit prototype using ECMAScript 5 (IE 9+)
MyError.prototype = Object.create(Error.prototype, {
constructor: {
value: MyError,
writable: true,
configurable: true
}
});
var myError = new MyError("message");
console.log("The message is: '" + myError.message + "'"); // The message is: 'message'
console.log(myError instanceof Error); // true
console.log(myError instanceof MyError); // true
console.log(myError.toString()); // MyError: message
console.log(myError.stack); // MyError: message \n
// <stack trace ...>
//for EMCAScript 4 or ealier (IE 8 or ealier), inherit prototype this way instead of above code:
/*
var IntermediateInheritor = function() {};
IntermediateInheritor.prototype = Error.prototype;
MyError.prototype = new IntermediateInheritor();
*/
您可能需要采取一些技巧来枚举tmp错误的所有不可枚举属性来设置它们,而不是只显式设置stack和message,但是ie<9不支持这种技巧
发布于 2017-06-15 00:09:57
在ES2015中,您可以使用class干净利落地完成此操作:
class NotImplemented extends Error {
constructor(message = "", ...args) {
super(message, ...args);
this.message = message + " has not yet been implemented.";
}
}这不会修改全局Error原型,允许您自定义message、name和其他属性,并正确捕获堆栈。它的可读性也很好。
当然,如果您的代码将在较旧的浏览器上运行,则可能需要使用像babel这样的工具。
https://stackoverflow.com/questions/783818
复制相似问题