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.