是否有可能修改错误的构造函数,以便它包含错误被引发的上下文?

叫我疯了,但我想要所有的JavaScript错误揭露了这种情况,当他们被抛出。 很难用英文解释,更容易解释我想要的代码:

 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

在抛出之前只需附加属性到你的错误(也许用一个很好的函数来包装它):

 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:

 function ContextifiedError (message, context) { var err = new Error(message); err.context = context; return err; } 

然后你throw ContextifiedError('something', this)

编辑:正如@BenjaminGruenbaum指出,使用助手时,堆栈跟踪是closures的。 如果你在乎,你可以写出一个更长,但更正确的帮手:

 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属性(请参阅本文以获取解释)。 其余的是样板。

然后你可以throw new ContextifiedError('something', this)