Nodejitsu

Save time managing and deploying your node.js app. Code faster with jitsu and npm

Using sys.inherits in node.js

About the author

Name
Location
Worldwide
nodejitsu nodejitsu

Whatever your opinion of prototypical inheritance in javascript, from a marco level it is clearly important when one considers DRY throughout a given codebase. The node.js 'sys' module exposes a simple way of accomplishing inheritance through sys.inherits. In this article we will explore how this method works and how you can use it to create more robust and modular code in nodejs.

Let's take a look at the code from core:

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

At a high level, what this method does is set the prototype of the subclass ('ctor') to a new instance of the prototype of the super class ('superCtor').


Developing with sys.inherits

Using sys.inherits in your own code is relatively simple. Let's explore this using a simple node example:

var sys = require('sys'),  
    events = require('events');

var MyClass = function () {  
  events.EventEmitter.call(this);
  // Put your constructor logic here
};

sys.inherits(MyClass, events.EventEmitter);

exports.MyClass = MyClass;  

What the above code does is create a new object 'MyClass' that inherits from the node.js core EventEmitter prototype. What this means is that anytime we require 'my-module' we can create a new instance of MyClass and use it just as we would use an EventEmitter instance. Here's a quick sample:

var sys = require('sys'),  
    myModule = require('./my-module');

var emitter = new myModule.MyClass();  
emitter.on('myevent', function () {  
  sys.puts('myevent was raised');
});

emitter.emit('myevent');  


Gotchas for sys.inherits

When declaring object prototypes in javascript, there are two distinct approaches: set the prototype as a single JSON object, or set the properties of the prototype individually. While I personally view the former as more stylistically pleasing when reading code, the latter is the approach that must be employed when using sys.inherits. This is because sys.inherits sets the entire prototype of the 'subclass'. Here's an illustrative example:

var sys = require('sys'),  
    events = require('events');

var MyClass = function () {  
  events.EventEmitter.call(this);
  // Put your constructor logic here
};

sys.inherits(MyClass, events.EventEmitter);

MyClass.prototype = {  
  myMethod: function () {
    sys.puts("Calling myMethod...");
  }
};

exports.MyClass = MyClass;  

In the above code the lines 'MyClass.prototype = { (...) }' overrides the prototype that is set by the preceding call to sys.inherits. The preferred implementation would be:

var sys = require('sys'),  
    events = require('events');

var MyClass = function () {  
  events.EventEmitter.call(this);
  // Put your constructor logic here
};

sys.inherits(MyClass, events.EventEmitter);

MyClass.prototype.myMethod = function () {  
  sys.puts("Calling myMethod...");
}

exports.MyClass = MyClass;  

In the latter example you can see that we set the property 'myMethod' of the 'MyClass' prototype explicitly, there by avoiding overriding the prototype that is set by the call to sys.inherits.


Wrapping up

There has been some discussion on the node.js mailing list regarding deprecating or removing sys.inherits, but the consensus has been that it will remain since it is used throughout node.js core, mostly to inherit from events.EventEmitter (see here, here, and here for some examples). I hope that this has been helpful for you and your development efforts using node.js.



UPDATE: The 'sys' module has been renamed to 'util' in node versions above 0.3.0