Search code examples
javascriptnode.jsinheritanceprototypeprototypal-inheritance

Can someone explain what util.inherits does in more laymans terms?


http://nodejs.org/docs/latest/api/util.html#util_util_inherits_constructor_superconstructor

In the above documentation they talk about util.inherits which takes two constructors. I'm trying to wrap my brain around the code sample they provide. I know what a Stream is and I know what an EventEmitter is and I understand why you'd want to make a stream inherit from EventEmitter but I'm really confused about how they're doing it.

What exactly is util.inherits doing? And why to they create a new constructor that invokes events.EventEmitter.call(this);? What is the difference between this strange way of doing things and just creating a new instance of EventEmitter and setting it to MyStream.prototype?

Here is the code sample from the article for convenience:

var util = require("util");
var events = require("events");

function MyStream() {
    events.EventEmitter.call(this);
}

util.inherits(MyStream, events.EventEmitter);

MyStream.prototype.write = function(data) {
    this.emit("data", data);
}

var stream = new MyStream();

console.log(stream instanceof events.EventEmitter); // true
console.log(MyStream.super_ === events.EventEmitter); // true

stream.on("data", function(data) {
    console.log('Received data: "' + data + '"');
})
stream.write("It works!"); // Received data: "It works!"

Solution

  • You can find the implementation of util.inherits here:

    exports.inherits = function(ctor, superCtor) {
      ctor.super_ = superCtor;
      ctor.prototype = Object.create(superCtor.prototype, {
        constructor: {
          value: ctor,
          enumerable: false,
          writable: true,
          configurable: true
        }
      });
    };
    

    It is essentially doing what you are describing (creating an instance of events.EventEmitter.prototype and setting that as the prototype of MyStream) along with attaching attaching events.EventEmitter to MyStream.super_.

    The events.EventEmitter.call(this); invokes the events.EventEmitter constructor so that it gets executed whenever a new MyStream is created. This is equivalent to calling super() in other languages like Java.