出于某种原因,在下面的代码段中,构造函数委托似乎不起作用:
function NotImplementedError() {
Error.apply(this, arguments);
}
NotImplementedError.prototype = new Error();
var nie = new NotImplementedError("some message");
console.log("The message is: '"+nie.message+"'")
运行该命令得到的消息是:"。有什么想法,为什么,或者是否有更好的方法来创建一个新的错误子类?是否有一个问题,应用到本机错误构造函数,我不知道?
如果你使用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
这部分的标准可以解释为什么错误。Apply调用不会初始化对象:
15.11.1错误构造函数作为函数调用
当Error作为函数而不是构造函数调用时,它会创建和
初始化一个新的Error对象。因此函数调用Error(…)是
等价于对象创建表达式new Error(…
相同的参数。
在这种情况下,Error函数可能确定它没有作为构造函数被调用,因此它返回一个新的Error实例,而不是初始化this对象。
用下面的代码进行测试似乎证明了这就是实际发生的情况:
function NotImplementedError() {
var returned = Error.apply(this, arguments);
console.log("returned.message = '" + returned.message + "'");
console.log("this.message = '" + this.message + "'");
}
NotImplementedError.prototype = new Error();
var nie = new NotImplementedError("some message");
运行此命令时输出如下:
returned.message = 'some message'
this.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!