I have been using Node since 0.11/0.12 so correct me if this is a matter of coming relatively late to the party.
I am trying to understand the difference between using util.inherits(Son, Dad)
and simply extending the prototype of Son.prototype = [new] Dad()
.
For this example I am subclassing a Transform stream using util.inherits
first:
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)
The above seems to be the most common way to go about this in Node. The following (extending the prototype) works just as well (seemingly), and it's simpler:
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)
For the record, I know there is through2
, which has a very simple interface, and do help reducing a few lines of code (see below), but I am trying to understand what is going under the hood, hence the question.
var thru = require("through2")(function (chunk, encoding, done) {
this.push(/* transform chunk! */)
done()
})
process.stdin.pipe(stream).pipe(process.stdout)
So, what are the differences between util.inherits
and extending the prototype in Node?
Inheritance enables you to define a class that takes all the functionality from a parent class and allows you to add more. Using class inheritance, a class can inherit all the methods and properties of another class. Inheritance is a useful feature that allows code reusability.
By default, each class in Node. js can extend only a single class. That means, to inherit from multiple classes, you'd need to create a hierarchy of classes that extend each other.
To create a class inheritance, use the extends keyword.
JavaScript does not support multiple inheritance, but mixins can be implemented by copying methods into prototype.
If this is the implementation of util.inherits it only does the following for you:
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
}
This is not a problem in Nodejs but in browsers that don't support a second argument to Object.create (because the polyfil does not allow it) you can repair the constructor in the following way:
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;
The extra thing it does is setting Child.super_ so in Child you can do:
function Child(){
Child.super_.call(this);//re use parent constructor
//same as Parent.call(this);
}
For more information on prototype and constructor functions you can read this answer.
According to the following, you are sub classing Transform incorrectly:
In classes that extend the Transform class, make sure to call the constructor so that the buffering settings can be properly initialized.
So the correct code should call it's constructor (you are not calling Transform with new but maybe the constructor has a way of handling faulty calls).
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With