home nodejitsu.com


Vote on HN

About the author

Name
Charlie Robbins
indexzero
indexzero
Location
New York, NY

About this article

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

Also by this author

  • waiting for godot
  • writing cli apps with flatiron

About nodejitsu

nodejitsu is a node.js application hosting company from new york city.

we are community leaders in the node.js project.

we build awesome open-source projects that you love and use.

Follow @nodejitsu

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