`util.inherits` 和在 NodeJS 中扩展原型之间的区别
Difference between `util.inherits` and extending the prototype in NodeJS
我从 0.11/0.12 开始就一直在使用 Node,所以如果这是一个来晚了的问题,请纠正我。
我试图理解使用 util.inherits(Son, Dad)
和简单地扩展 Son.prototype = [new] Dad()
的原型之间的区别。
对于这个例子,我首先使用 util.inherits
对 Transform stream 进行子类化:
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.js 中最常见的处理方式。下面的(扩展原型)效果一样(表面上),而且更简单:
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)
郑重声明,我知道有 through2
,它有一个非常简单的界面,确实有助于减少几行代码(见下文),但我想了解下面的内容引擎盖,因此问题。
var thru = require("through2")(function (chunk, encoding, done) {
this.push(/* transform chunk! */)
done()
})
process.stdin.pipe(stream).pipe(process.stdout)
那么,util.inherits
和在 Node 中扩展原型有什么区别?
如果 this 是 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_ 所以在 Child 中你可以做:
function Child(){
Child.super_.call(this);//re use parent constructor
//same as Parent.call(this);
}
有关原型和构造函数的更多信息,您可以阅读 this answer。
根据 following,您对 Transform 的子分类不正确:
In classes that extend the Transform class, make sure to call the
constructor so that the buffering settings can be properly
initialized.
所以正确的代码应该调用它的构造函数(你不是用 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)
我从 0.11/0.12 开始就一直在使用 Node,所以如果这是一个来晚了的问题,请纠正我。
我试图理解使用 util.inherits(Son, Dad)
和简单地扩展 Son.prototype = [new] Dad()
的原型之间的区别。
对于这个例子,我首先使用 util.inherits
对 Transform stream 进行子类化:
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.js 中最常见的处理方式。下面的(扩展原型)效果一样(表面上),而且更简单:
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)
郑重声明,我知道有 through2
,它有一个非常简单的界面,确实有助于减少几行代码(见下文),但我想了解下面的内容引擎盖,因此问题。
var thru = require("through2")(function (chunk, encoding, done) {
this.push(/* transform chunk! */)
done()
})
process.stdin.pipe(stream).pipe(process.stdout)
那么,util.inherits
和在 Node 中扩展原型有什么区别?
如果 this 是 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_ 所以在 Child 中你可以做:
function Child(){
Child.super_.call(this);//re use parent constructor
//same as Parent.call(this);
}
有关原型和构造函数的更多信息,您可以阅读 this answer。
根据 following,您对 Transform 的子分类不正确:
In classes that extend the Transform class, make sure to call the constructor so that the buffering settings can be properly initialized.
所以正确的代码应该调用它的构造函数(你不是用 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)