OOP Programming in Javascript with Node.js

Solution 1:

2 months later

Maybe you do need a library, ES5 is verbose as hell so I've created pd

Original answer

I am looking for a OOP solution / library for Node.js.

You don't need a library. You have ES5.

JavaScript does not have classical OOP. It has prototyping OOP.

This means you have only objects. The only thing you can do with objects is extend, manipulate and clone them.

Manipulate

var o = {};
o.foo = "bar";

Extend

var o = someObject;
Object.defineProperties(o, {
  "foo": { value: "foo" },
  "bar": { value: "bar" }
  "method": { value: function () { } }
}

Clone

var o = someObject;
var p = Object.create(o);

Clone and extend

var o = someObject;
var p = Object.create(o, {
  "foo": { value: "foo" },
  "bar": { value: "bar" }
  "method": { value: function () { } }
}

It's important to understand how Object.create, Object.defineProperty and Object.defineProperties work.

The cloning operation isn't actually cloning. It's creating a new object from a blueprint. A blueprint is an object. It places the blueprint in the [[Prototype]]. The [[Prototype]] lives in the .__proto__ property which I'll use for demonstration.

var o = {};
var p = Object.create(o);
p.__proto__ === o; // true
var q =  Object.create(p);
q.__proto__.__proto__ === o;
var r = Object.create(q);
r.__proto__.__proto__.__proto__ === o;

Disclaimer: .__proto__ is deprecated. Don't use it in code. It has it's uses for debugging and sanity checks though.

The main point here is that accessing properties from o in r it has to walk 3 levels up the prototype chain and this gets expensive. To solve that problem, rather then cloning random objects you should clone specific blueprints (and you should have one blueprint per object).

// Parent blueprint
var Parent = (function _Parent() {
  // create blank object
  var self = Object.create({});

  // object logic

  return self;
}());

// factory function
var createParent = function _createParent(foo) {
  // create a object with a Parent prototype
  return Object.create(Parent, {
    foo: { value: foo }
  });
}

var Child = (function _Child() {
  var self = Object.create(Parent);

  // other stuff

  return self;
}());

var createChild = function _createChild(bar) {
  return Object.create(Child, {
    bar: { value: bar }
  })
};

Here's a snippet from some code I'm working on that you can use as an example:

var Sketchpad = (function _SketchPad() {
    var self = Object.create({});

    var mousemove = function _mousemove(e) {
        this.drawLine(e);
    };

    self._init = function _init() {
        this.$elem.bind({
            "mousemove": mousemove.bind(this),
        });
        this.pens = {};

        $("#clear").bind("click", this.clear.bind(this));
        $("#undo").bind("click", (function _undoPath() {
            this.pen.undo();
        }).bind(this));

        return this;
    };

    self.clear = function() {
        this.paper.clear();    
    };

    return self;    
}());

createSketch = function _createSketchPad(id, w, h) {
    var paper = Raphael(id, w, h);
    var pen = createPen(paper);
    var o = Object.create(Sketchpad, {
        paper: { value: paper },
        $elem: { value: $("#" + id) },
        pen: { 
            get: function() { return pen; },
            set: function(v) { pen = v; }
        }
    });

    return o._init();
};

Solution 2:

MooTools is one of the best libraries in terms of OOP Javascript.

You can create classes, interfaces, use inheritance, etc.

Documentation http://mootools.net/docs/core

Tutorial - MooTools OOP http://www.phpeveryday.com/articles/MooTools-Basic-Creating-Classes-MooTools-P919.html

Solution 3:

You might also be interested in GNU ease.js. If you are not interested in the library itself, its manual goes extensively into the implementation details.

You could also see the author's paper on Classical OOP in ECMAScript.