出于某种原因,在下面的代码段中,构造函数委托似乎不起作用:
function NotImplementedError() {
Error.apply(this, arguments);
}
NotImplementedError.prototype = new Error();
var nie = new NotImplementedError("some message");
console.log("The message is: '"+nie.message+"'")
运行该命令得到的消息是:"。有什么想法,为什么,或者是否有更好的方法来创建一个新的错误子类?是否有一个问题,应用到本机错误构造函数,我不知道?
上面的很多方法都不起作用。
最后一个是一个实际的错误。如果您使用字符串,它看起来很好,但它不会提供堆栈跟踪。如果你抛出错误,你不能有“Uncaught BadError: bad”,所以你必须删除自定义错误(遗憾的是)。如果你抛出一个对象,它看起来有点偏离,最后一个只是一个平均错误。
此方法创建一个具有自定义名称的错误,同时保留堆栈跟踪:
var errProto = Object.create(Error.prototype, {
constructor: {
value: Error,
enumerable: false,
writable: true,
configurable: true
}
})
var isFirefox = !!window.InstallTrigger
// Hide stack for Firefox only, as stacks can cause problems with high "frame" counts.
function createError(name, message, hideStack) {
if (message == null) {
message = ""
}
var customError = Error(message)
customError.name = name
Object.setPrototypeOf(customError, errProto)
if (isFirefox && hideStack) {
customError.stack = ""
} else if (isFirefox) {
var stack = customError.stack
var newline = stack.indexOf("\n") + 1
stack = stack.slice(newline)
customError.stack = stack
var split = stack.split(":")
if (split.length > 4) {
var a = split[3]
var b = split[4]
var t = b.slice(0, b.indexOf("\n"))
customError.lineNumber = Number(a)
customError.columnNumber = Number(t)
}
} else {
var stack = customError.stack
var split = stack.split("\n")
var secondPart = split.slice(2).join("\n")
stack = split[0] + "\n" + secondPart
customError.stack = stack
var split = secondPart.split(":")
var a = split[2]
var b = split[3]
}
throw customError
}
var frame = 0
function aFunction() {
if (++frame === 100) {
createError("LazyError", "function getting lazy", false, true)
} else {
requestAnimationFrame(aFunction)
}
}
setTimeout(aFunction, Math.random() * 500)
* {
font-family: Verdana;
}
Check your inspector!
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
以上所有的答案都很糟糕,真的。即使是107个向上的那个!真正的答案在这里:
从Error对象继承- message属性在哪里?
TL; diana:
a .没有设置message的原因是Error是一个函数,它返回一个新的Error对象,并且不以任何方式操作它。
B.正确的方法是从构造函数返回apply的结果,以及以通常复杂的javascript方式设置原型:
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 Error的所有不可枚举属性来设置它们,而不是显式地只设置stack和message,但是ie<9不支持这种技巧
如果你使用Node/Chrome。下面的代码片段将为您提供满足以下要求的扩展。
err instanceof Error
err instanceof CustomErrorType
console.log() returns [CustomErrorType] when created with a message
console.log() returns [CustomErrorType: message] when created without a message
throw/stack provides the information at the point the error was created.
Works optimally in Node.JS, and Chrome.
Will pass instanceof checks in Chrome, Safari, Firefox and IE 8+, but will not have a valid stack outside of Chrome/Safari. I'm OK with that because I can debug in chrome, but code which requires specific error types will still function cross browser. If you need Node only you can easily remove the if statements and you're good to go.
片段
var CustomErrorType = function(message) {
if (Object.defineProperty) {
Object.defineProperty(this, "message", {
value : message || "",
enumerable : false
});
} else {
this.message = message;
}
if (Error.captureStackTrace) {
Error.captureStackTrace(this, CustomErrorType);
}
}
CustomErrorType.prototype = new Error();
CustomErrorType.prototype.name = "CustomErrorType";
使用
var err = new CustomErrorType("foo");
输出
var err = new CustomErrorType("foo");
console.log(err);
console.log(err.stack);
[CustomErrorType: foo]
CustomErrorType: foo
at Object.<anonymous> (/errorTest.js:27:12)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:906:3
/errorTest.js:30
throw err;
^
CustomErrorType: foo
at Object.<anonymous> (/errorTest.js:27:12)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:906:3