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中没有办法使Error
在new GTError
expression式中填充由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); }