NodeJS对象的inheritance

我有一个扩展Error对象的自定义错误对象:

function GTError(reason, loglevel, meta) { winston.log(loglevel, reason, meta); GTError.super_.apply(this, arguments); } util.inherits(GTError, Error); 

我知道这是行不通的, 这个问题有解决方法。 我的问题不是如何解决这个问题,我的问题是为什么它不工作? 为什么要调用GTError.super_.apply(this, arguments); (其中GTError.super_Error )不填充此message属性?

在这里输入图像说明

你能解释一下吗? 谢谢

我的问题不是如何解决这个问题,我的问题是为什么它不工作?

因为Error函数总是返回一个新的实例,即使你不用new调用它; 它不会修改调用它时引用的对象。 从ES5规范 :

Error作为一个函数而不是构造函数被调用时,它会创build并初始化一个新的Error对象。 因此,调用Error(…)的函数等同于具有相同参数的对象创buildexpression式new Error(…)

所以在你的代码中, GTError.super_.apply(this, arguments); (其中GTError.super_Error )实际上是一个无操作,因为它创build并抛出一个Error对象,而不是使Error成为传递的对象。 事实上,在ES5中没有办法使Errornew GTErrorexpression式中填充由new创build的对象,因为定义了Error

TC-39委员会在ES2015中修正了这个问题,但只有当你使用新的类的时候(为了保持向后兼容性)。


我知道你说你只是想知道为什么,但是对于其他人:在ES2015和更高版本中,你可以通过新的class东西正确的子类Error 。 至less在严格模式下的Node v4中支持此语法,并且在Node v6中通用。 以下内容可用于任何最新版本的Chrome或Firefox:

 let winston = { log: function(...args) { console.log("log", ...args); } }; class GTError extends Error { constructor(reason, loglevel, meta) { winston.log(loglevel, reason, meta); super(reason, loglevel, meta); } } try { throw new GTError("reason", 10, "meta"); } catch (e) { console.log(e instanceof Error); console.log(e instanceof GTError); console.log(e.message); }