叫我疯了,但是我希望所有JavaScript错误在它们被抛出时公开this
的上下文。很难用英语解释,更容易解释我想要的代码:
var Person = function() {
this.name = 'Chuck';
}
Person.prototype.speak = function() {
throw new Error('muted!');
console.log('My name is', this.name);
}
var person = new Person();
try {
person.speak();
}
catch(error) {
console.log(error.context.name, 'could not speak.');
}
我是否可以自动填充error.context
属性,以便上面的代码可以使用?我对任何疯狂的技巧和使用下一版本的JavaScript或node.js持开放态度。
编辑:我想在不使用自定义错误的情况下执行此操作。这样我就可以捕获任何非自定义错误,仍然可以访问context
。
答案 0 :(得分:6)
在抛出错误之前,只需将属性附加到错误中(可能用一个很好的函数包装它):
var obj = {
foo : 'thingonabob',
ouch : function () {
var err = new Error();
err.context = this;
throw err;
}
};
try {
obj.ouch();
}
catch (e) {
console.error('The darned %s is at it again!', e.context.foo)
}
可能的辅助函数:
function ContextifiedError (message, context) {
var err = new Error(message);
err.context = context;
return err;
}
然后你throw ContextifiedError('something', this)
编辑:正如@BenjaminGruenbaum指出的那样,使用帮助程序时堆栈跟踪会被一个关闭。如果你关心,你可以写出一个更长但更有道理的帮手:
function ContextifiedError (message, context) {
this.context = context;
this.type = 'ContextifiedError';
Error.call(this, message);
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
}
}
ContextifiedError.prototype = Error.prototype;
ContextifiedError.prototype.constructor = ContextifiedError;
Error.call
用于调用我们自己的“父亲构造函数”。 Error.captureStackTrace
,在现代浏览器中,确保我们拥有正确的.stack
属性(有关说明,请参阅this article)。其余的是样板。
然后你可以throw new ContextifiedError('something', this)
。