home nodejitsu.com

about the author

Name:
Charlie Robbins
Github:
indexzero
Twitter:
indexzero
Location:
New York, NY

about this article

Date Released:
Tuesday, Sep 21 2010
Code Examples:
  • correct-module.js

also by this author

  • writing cli apps with flatiron
  • introducing flatiron
  • scaling isomorphic javascript code
  • the nodejs philosophy
  • distribute nodejs apps with hookio
  • analyze nodejs dependencies like magic
  • updating node http proxy
  • rest easy test any api in nodejs
  • 6 must have nodejs modules
  • a simple webservice in nodejs
  • put your logs anywhere with winston
  • logging logs and loggly in nodejs
  • keep a nodejs server up with forever
  • nodejs cloud server in three minutes
  • jsdom jquery in 5 lines on nodejs

about nodejitsu

nodejitsu is a node.js application hosting and martial arts training company.

we are evangelists and community leaders in the node.js project.

we build awesome open-source projects and keep your node.js apps running on our node.js hosting platform.

Using sys.inherits in node.js

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