Skip to content

Instantly share code, notes, and snippets.

Created October 31, 2012 22:29
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/3990372 to your computer and use it in GitHub Desktop.
Save anonymous/3990372 to your computer and use it in GitHub Desktop.
Simple LightWeight OOP in Node.js
var inherits = require('util').inherits;
function Class(obj, options) {
function F() {
F.prototype.constructor.apply(this, arguments);
}
if (options && options.baseClass) {
inherits(F, options.baseClass);
}
for (var property in obj) {
var value = obj[property];
F.prototype[property] = value; //extend the prototype to meet our "class" layout
}
return F;
}
var assert = require("assert"),
util = require('util');
var Base = Class({
constructor: function (text) {
this.text = text;
},
getText: function () {
return this.text;
}
});
var Derived = Class({
constructor: function (text, prefix) {
Base.prototype.constructor.call(this, text);
this.prefix = prefix;
},
getText: function () {
return this.prefix + Base.prototype.getText.apply(this) + this.prefix;
}
}, {
baseClass: Base
});
var Derived2 = Class({
constructor: function (text, prefix, color) {
Derived.prototype.constructor.call(this, text, prefix);
this.color = color;
},
getText: function () {
return this.color + Derived.prototype.getText.apply(this);
},
getColor: function () {
return this.color;
}
}, {
baseClass: Derived
});
var base = new Base("base"),
derived = new Derived("derived", "!"),
derived2 = new Derived2("derived2", "!", "red");
//mocha test suite, all tests pass.
describe('Class', function () {
describe('API', function () {
it('Class should be callable', function () {
assert.equal(typeof Class === "function", true);
});
it('Class should return a function', function () {
assert.equal(typeof Base === "function", true);
assert.equal(typeof Derived === "function", true);
assert.equal(typeof Derived2 === "function", true);
});
it('derived should have same interface as base', function () {
assert.equal(typeof base.getText === "function", true);
assert.equal(typeof base.getText === typeof derived.getText, true);
assert.equal(typeof base.getText === typeof derived2.getText, true);
});
});
describe('Functional', function () {
it('base should be an instanceof Base', function () {
assert.equal(base instanceof Base, true);
});
it('derived should be an instanceof Derived', function () {
assert.equal(derived instanceof Derived, true);
});
it('derived2 should be an instanceof Derived2', function () {
assert.equal(derived2 instanceof Derived2, true);
});
it('derived should be an instanceof Base', function () {
assert.equal(derived instanceof Base, true);
});
it('derived2 should be an instanceof Derived', function () {
assert.equal(derived2 instanceof Derived, true);
});
it('base should NOT be an instanceof Derived', function () {
assert.equal(base instanceof Derived, false);
});
describe('#getText', function () {
it('base.getText() should return "base"', function () {
assert.equal(base.getText(), "base");
});
it('derived.getText() should return "!derived!"', function () {
assert.equal(derived.getText(), "!derived!");
});
it('derived2.getText() should return "red!derived!"', function () {
assert.equal(derived2.getText(), "red!derived2!");
});
});
});
});
// However. The return value from Class is 100% compatible with pure JavaScript inheritance,
// so we can replace to example the Derived and prototype with the following:
function Derived(text, prefix) {
Base.call(this, text);
this.prefix = prefix;
}
util.inherits(Derived, Base);
Derived.prototype.getText = function () {
return this.prefix + Base.prototype.getText.apply(this) + this.prefix;
};
//without any tests fail.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment