`util.inherits`和在NodeJS中扩展原型的区别

我从0.11 / 0.12开始一直在使用Node,所以如果这是晚会来得晚的话,请纠正我。

我想了解使用util.inherits(Son, Dad)和简单地扩展Son.prototype = [new] Dad()的原型之间的Son.prototype = [new] Dad()

对于这个例子,我首先使用util.inherits了一个Transformstream :

 var util = require('util') var Transform = require('stream').Transform util.inherits(TStream, Transform) function TStream () { Transform.call(this) } TStream.prototype._transform = function(chunk, encoding, done) { this.push(/* transform chunk! */) done() } process.stdin.pipe(new TStream()).pipe(process.stdout) 

以上似乎是Node中最常用的方法。 以下(扩展原型)的工作方式(貌似)也很简单:

 function TStream() {} TStream.prototype = require("stream").Transform() TStream.prototype._transform = function (chunk, encoding, done) { this.push(/* transform chunk! */) done() } process.stdin.pipe(new TStream()).pipe(process.stdout) 

为了logging,我知道有通过through2 ,它有一个非常简单的界面,并帮助减less几行代码(见下文),但我想了解什么是在引擎盖下, 因此的问题。

 var thru = require("through2")(function (chunk, encoding, done) { this.push(/* transform chunk! */) done() }) process.stdin.pipe(stream).pipe(process.stdout) 

那么, util.inherits和Node中的原型之间有什么区别呢?

如果这是util.inherits的实现,它只会为你做以下事情:

  Child.super_ = Parent; //set prototype using Object.create Child.prototype = Object.create(Parent.prototype, { constructor: {//repair the prototype.constructor value: Child, enumerable: false, writable: true, configurable: true } 

这在Nodejs中不是问题,但是在不支持Object.create的第二个参数的浏览器中(因为polyfil不允许),可以按照以下方式修复构造函数:

 Child.prototype = Object.create(Parent.prototype);//if you polyfilled Object.create //Child.prototype.constructor is now Parent so we should repair it Child.prototype.constructor = Child; 

它做的额外的事情是设置Child.super_,所以在你可以做的孩子:

 function Child(){ Child.super_.call(this);//re use parent constructor //same as Parent.call(this); } 

有关原型和构造函数的更多信息,您可以阅读这个答案 。

根据以下内容 ,您正在进行分类不正确的转换:

在扩展Transform类的类中,确保调用构造函数,以便可以正确地初始化缓冲设置。

所以正确的代码应该调用它的构造函数(你不是用new来调用Transform,也许这个构造函数有办法处理错误的调用)。

 var Transform = require("stream").Transform; function TStream() { Transform.call(this);//you did not do that in your second example } //your code sets prototype to an INSTANCE of Transform // and forgets to call the constructor with new //TStream.prototype = require("stream").Transform() TStream.prototype = Object.create(Transform.prototype); TStream.prototype.constructor = TStream; TStream.prototype._transform = function (chunk, encoding, done) { this.push(/* transform chunk! */) done() } process.stdin.pipe(new TStream()).pipe(process.stdout)