Classes
Lightning-fast and flexible OOP Style Classes

Each Module, Controller, Service or Model is extended from a Class, we do this for many reasons but none as important as taking advantage of V8's Hidden Classes, Inline Caches & Optimizing Compiler to allow V8 to generate efficient and performant machine code so your application is as fast as humanly possible and then some.

Beauty is more important in computing than anywhere else in technology because software is so complicated. Beauty is the ultimate defence against complexity.
David Gelernter
  • Prototypal inheritance
  • Static inheritance
  • Setup and initialization methods
  • Easy callback (proxying/currying) creation
  • Lightning fast performance
    1. Takes advantage of V8's Hidden Classes & Inline Caches
    2. Takes advantage of V8's Optimizing Compiler which generates efficient machine code to run in place of your javascript Clean, Efficient and Optimized code
  • All Classes can emit and listen to events using EventEmitter

Proxy Functions

We strongly encourage the use of curried proxy functions, by doing so you are able to keep your code easy to read and maintain by using as little nesting as possible, this also means your code (function/s) is/are re-usable.

Example Usage

Take a look at our Module Loader Class for an in-depth look at how to use currying to your advantage.

Currying (proxy methods)

Read Currying on Wikipedia for an in-depth explaination of currying.

Hidden Classes

Read Understanding Hidden Classes in V8 and View this Video for an indepth look at what Hidden Classes are and how they work in V8.


// This example file exports a function that will have "Class" injected into it via the clever-injector
module.exports = function( Class ) {
  return Class.extend(
  /* @Class */
  {
    // Static attributes or methods
  },
  /* @Prototype */
  {
    // Instance attributes or methods
  });
};

Extend's arguments

You can call .extend() with only the Static/Class object instead of defining both


Every Class will provide an extend function that can be used to extend the functionality of a Class with some new functionality as provided in the Static and Prototype of the extend call.

A good example of class extension is the Controller class (in lib folder), it extends from Class and every module/s controller/s extend from Controller.

When you overload a method from a parent class, you can call the parents method by using this._super()

var Monster = Class.extend(
/* @Class */
{
  count: 0
},
/* @Prototype */
{
  init: function( name ) {

    // saves name on the monster instance
    this.name = name;

    // sets the health
    this.health = 10;

    // increments count
    this.Class.count++;
  },
  eat: function( smallChildren ){
    this.health += smallChildren;
  },
  fight: function() {
    this.health -= 2;
  }
});

hydra = new Monster('hydra');
dragon = new Monster('dragon');

console.log(hydra.name)     // -> hydra
console.log(Monster.count)  // -> 2

hydra.eat(2);
console.log(hydra.health);  // health = 12

dragon.fight();    
console.log(dragon.health); // health = 8

var SeaMonster = Monster.extend({
    eat : function(smallChildren)
    {
        this._super(smallChildren / 2);
    },
    fight : function()
    {
        this.health -= 1;
    }
});

var lochNess = new SeaMonster('Loch Ness');

lochNess.eat(4);
console.log("Loch Ness ate. Health: " + lochNess.health); // -> 12

lochNess.fight();
console.log("Loch Ness fought. Health: " + lochNess.health); // -> 11

Here is an example of creating a class and using the proxy function as well as emitting events.

var Class = require( 'classes' ).Class;

module.exports = Class.extend({
  files: null,

  init: function() {
    this.files = [];
    this.getFiles( __dirname );
    this.emit( 'init' );
  },

  getFiles: function( dir ) {
    fs.readdir( dir, this.proxy( 'handleGetFiles', dir ) );
  },

  // The dir variable has been curried into this function by getFiles()
  handleGetFiles: function( dir, err, files ) {
    if ( !err ) {
      this.files = files;
    } else {
      console.error( err );
    }
  }
});

Needs more information

This section of the documentation is either out-dated or incomplete, please ask for help in github or gitter if you need more information.

Needs more information

This section of the documentation is either out-dated or incomplete, please ask for help in github or gitter if you need more information.

Proxies are a helpful way of flattening your code, you don't need to nest or repeat yourself - structure it out into something more modular and re-usable.


var Handler = Class.extend({
    init : function(content, headers)
    {
        this._headers = headers;
        this._content = content;
    },

    /* Prototype */
    writeHead : function(response)
    {
        response.writeHead(200, this._headers);
    },

    handle : function(request, response)
    {
        this.writeHead(response);
        response.end(this._content);
    }
});

var handler = new Handler('Hello World from ResponseHandler\n', { 'Content-Type': 'text/plain' });

var http = require('http');
http.createServer(handler.proxy('handle')).listen(1337, "127.0.0.1");