2009-06-22

Property Inheritance (with a Constructor) in JavaScript

In JSMeta, I needed instances of a particular "class" (JavaScript doesn't have classes, per se, so what I really mean is objects initialized by a particular "constructor" Function) to "magically" (invisibly, automatically) inherit existing properies from another instance of that "class".

I created the following generic function that does just that:



function spawnOf(progenitor) {
// obtain a reference to the function
// that created the object
var Ctor = typeof(progenitor.constructor)!='undefined'
? progenitor.constructor
: getGlobal()[Object.prototype.toString.call(
progenitor).match(/^\[object\s(.*)\]$/)[1]];
// the below shouldn't ever happen
// (except on undefined or null)
if (typeof Ctor != 'function')
throw 'constructor not found';
// save the original prototype of
// the constructor function
var origProto = Ctor.prototype;
// replace the constructor function's
// prototype with the progenitor object
Ctor.prototype = progenitor;
// create a new "child" object, using the same
// constructor function as the progenitor object.
var childObject = new Ctor();
// replace the constructor function's prototype.
Ctor.prototype = origProto;
return childObject;
}

// from http://www.nczonline.net/blog/2008/04/20/get-the-javascript-global/
// by Nicholas C. Zakas
function getGlobal() {
return (function() {
return this;
}).call(null);
}


Here's an example of how to use it. It's useful in situations where you want to create a new object using a constructor function, but you also want the object to invisibly/automatically inherit its properties from its progenitor.



// for v8(.exe) or jsc(.exe) or whatever
// mozilla's js .exe are named
if (typeof(alert)=='undefined') alert=print;

function Gungan() {
this.toString = function() {
return "_|meesa Gungan|_"
};
if (this.constructor
===Gungan.prototype.constructor) {
// odd quirk here; this is never true in
// v8: (Gungan.prototype instanceof Gungan)
this.parent = Gungan.prototype;
}
}

var jarjar = new Gungan();

jarjar.iq = 100;

var jarjar_kid = spawnOf(jarjar);

alert(jarjar_kid.iq); // alerts "100"

jarjar_kid.iq = 85;

alert(jarjar.iq); // alerts "100"

alert(jarjar_kid.iq); // alerts "85"

alert(jarjar_kid.parent.iq); // alerts "100"

No comments:

Post a Comment