Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@GothAck
Created February 19, 2013 11:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save GothAck/4985004 to your computer and use it in GitHub Desktop.
Save GothAck/4985004 to your computer and use it in GitHub Desktop.
Example of Polymorphism in Node.js / ECMAScript / JavaScript
var types = require('./types');
var assert = require('assert');
var a = new types.MyPtt(7, 8);
assert(a instanceof types.Base, 'Inherits from Base');
assert(a instanceof types.MyPtt, 'Inherits from MyPtt (it\'s constructor)');
assert(typeof a.one === 'function', 'Has MyPtt "one" function');
assert(a.type === 'MyPtt', 'Has correct type')
console.log('a is MyPtt', a, a.constructor, a.__proto__);
console.log(Object.getPrototypeOf(a));
a.type = 'OtPtt';
assert(a instanceof types.Base, 'Inherits from Base');
assert(! (a instanceof types.MyPtt), 'Does not inherit from MyPtt (it\'s original constructor)');
assert(a instanceof types.OtPtt, 'Inherits from OtPtt (it\'s new constructor)');
assert(typeof a.one !== 'function', 'Does not have MyPtt "one" function');
assert(typeof a.two === 'function', 'Has OtPtt "two" function');
assert(a.type === 'OtPtt', 'Has correct type')
console.log('a is OtPtt', a, a.constructor, a.__proto__);
console.log(Object.getPrototypeOf(a));
var util = require('util');
function Base (thing) {
this.thing = thing;
}
Base.prototype.rar = function () {
console.log('rar', this.thing);
}
Base.prototype.__defineSetter__('type', function (type) {
// Check we have a subclass etc.
if (this.constructor === Base)
throw new Error('Can only set type on subprototypes of Base');
if (!module.exports[type])
throw new Error('No prototype ' + type);
if (module.exports[type].super_ !== Base)
throw new Error('Needs to be a subprototype of Base');
// Need to use defineProperty to stop constructor being enumarable
Object.defineProperty(this, 'constructor', {
value: module.exports[type]
, enumarable: false
});
// Strangely don't for __proto__, this is where the magic happens!
this.__proto__ = module.exports[type].prototype;
});
Base.prototype.__defineGetter__('type', function () {
// May as well return a sensible value :)
return this.constructor.name;
});
module.exports.Base = Base;
function MyPtt (thing, otherthing) {
this.constructor.super_.call(this, thing);
this.otherthing = otherthing;
}
util.inherits(MyPtt, Base);
MyPtt.prototype.one = function () { console.log(1) }
module.exports.MyPtt = MyPtt;
function OtPtt (thing, thing2) {
this.constructor.super_.call(this, thing);
this.thing2 = thing2;
}
util.inherits(OtPtt, Base);
OtPtt.prototype.two = function () { console.log(2) }
module.exports.OtPtt = OtPtt;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment