簡體   English   中英

`util.inherits`與NodeJS中的原型擴展之間的區別

[英]Difference between `util.inherits` and extending the prototype in NodeJS

我一直在使用Node自0.11 / 0.12,所以如果這是一個相對遲到的問題,請糾正我。

我試圖理解使用util.inherits(Son, Dad)和簡單地擴展Son.prototype = [new] Dad()的原型之間的Son.prototype = [new] Dad()

對於此示例,我首先使用util.inheritsTransform流進行子類化:

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM