Created
May 11, 2012 09:40
-
-
Save pete-otaqui/2658660 to your computer and use it in GitHub Desktop.
Prototypal inheritance in javascript using Object.create with functions getting a "parent" property to be able to call the method they overwrote
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Object.spawn for a more terse form of Object.create, | |
* with the super added bonus of giving all overriden | |
* functions a "parent" property which refers back to | |
* thing it was overriding ... like "parent" or "super" | |
* in classical OOP | |
* | |
* @link http://howtonode.org/prototypical-inheritance | |
* @param {Object} parent The parent object used in Object.create | |
* @param {Object} props The object containing properties, unlike Object.create doesn't need an extra level of abstraction, and all properties will be enumerable | |
* @return {Object} The newly created object | |
*/ | |
Object.spawn = function (parent, props) { | |
var defs = {}, key; | |
for (key in props) { | |
if (props.hasOwnProperty(key)) { | |
defs[key] = { | |
value: props[key], | |
enumerable: true | |
}; | |
// here's the "parent" magic. | |
// we make sure that both keys are functions, | |
// and the "child" doesn't already have a "parent" | |
if ( | |
typeof props[key] === 'function' && | |
typeof parent[key] === 'function' && | |
typeof props[key].parent === 'undefined' | |
) { | |
props[key].parent = parent[key]; | |
} | |
} | |
} | |
return Object.create(parent, defs); | |
}; | |
var Base = { | |
init: function() { | |
console.log('Base.init'); | |
// n.b. returning "this" from init functions is a nice pattern | |
return this; | |
} | |
}; | |
/* | |
Note that you could have used "arguments.callee" but that doesn't | |
work in strict mode, so in classic "Things To Do In Denver When | |
You're Dead" style: give it a name. | |
*/ | |
var Game = Object.spawn(Base, { | |
init: function Game_init() { | |
Game_init.parent.apply(this); | |
console.log('Game.init'); | |
return this; | |
} | |
}); | |
var Pong = Object.spawn(Game, { | |
init: function Pong_init() { | |
Pong_init.parent.apply(this); | |
console.log('Pong.init'); | |
return this; | |
} | |
}); | |
var pong = Object.spawn(Pong).init(); | |
/* Output: | |
Base.init | |
Game.init | |
Pong.init | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment