“util.inherits”和在NodeJS中扩展原型之间的区别
Difference between `util.inherits` and extending the prototype in NodeJS
我从0.11/01.12开始使用Node,所以如果这是一个来派对相对较晚的问题,请纠正我。
我试图理解使用util.inherits(Son, Dad)
和简单地扩展Son.prototype = [new] Dad()
的原型之间的区别。
对于这个例子,我首先使用util.inherits
对Transform流进行子类化:
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)
记录在案,我知道有through2
,它有一个非常简单的接口,确实有助于减少几行代码(见下文),但我正在努力了解幕后的情况,因此是个问题。
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,这样在Child中你就可以做:
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)
相关文章:
- “util.inherits”和在NodeJS中扩展原型之间的区别
- JavaScript:动态扩展原型是一种糟糕的做法
- 使用第二个原型扩展对象
- 用原型扩展Javascript Form对象
- javascript原生原型:扩展、添加和覆盖方法
- 使用原型扩展挖空视图模型
- 我可以用原型“扩展”jQuery对象吗?
- 如何通过其原型扩展jquery插件的公共方法
- 原型扩展jQuery在Internet Explorer中不起作用 - “不支持”
- 通过原型扩展数学对象不起作用
- 使用原型扩展另一个函数的函数
- ExtJS:在哪里定义基类的原型扩展
- 动态javascript原型扩展
- 如何在IE9中原型扩展文档对象
- 如何在字符串原型扩展方法中使用字符串方法
- Javascript原型扩展了删除子函数
- 用原型扩展基实例
- NodeList的原型扩展
- JavaScript原型扩展
- 而Number原型扩展中的循环调用函数一次,然后出现未定义的错误