Created
December 10, 2011 18:08
-
-
Save gordonbrander/1455798 to your computer and use it in GitHub Desktop.
Tiny Little JavaScript Classes
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
// Create a prototype bridge between two functions. | |
var __bridge = function(child, parent) { | |
function ctor() { this.constructor = child; } | |
ctor.prototype = parent.prototype; | |
child.prototype = new ctor(); | |
return child; | |
}; | |
// Merge any number of objects together. | |
// The first object has it's reference modified | |
// (doesn't return a new object). | |
// The last object property wins. | |
// | |
// Serves the same purpose as jQuery.extend and _.extend. | |
var __merge = function (obj) { | |
var objects = Array.prototype.slice.call(arguments, 1), | |
key, i, objN; | |
for (i=0; i < objects.length; i++) { | |
objN = objects[i]; | |
for (key in objN) { | |
// Don't copy built-in or inherited object properties. | |
if (!objN.hasOwnProperty(key)) continue; | |
obj[key] = objN[key]; | |
} | |
} | |
return obj; | |
}; | |
// Minimal classical inheritance via object literals. | |
// Inspired by jashkenas' Proposal: <https://gist.github.com/1329619>. | |
// | |
// Creates a constructor function -- all items in the object will get | |
// copied to the prototype. If the first argument is another | |
// constructor function, this class will create a prototype bridge. | |
// | |
// This approach only does prototype chaining and doesn't emulate | |
// super or static. | |
// | |
// Usage: | |
// | |
// var Bunny = __class({ | |
// hop: function (length) { ... } | |
// }); | |
// | |
// var JackRabbit = __class(Bunny, { | |
// constructor: function (type) { | |
// this.type = type; | |
// }, | |
// skip: function (length) { ... } | |
// }); | |
// | |
// var myJackRabbit = new Jackrabbit('grey'); | |
// myJackRabbit.hop(); | |
// myJackRabbit.skip(); | |
var __class = function (a, b) { | |
var obj, parent, child; | |
// Handle the two different argument formulations | |
// Case 1: parent, object. | |
// Case 2: object, undefined | |
b ? (parent = a, obj = b) : obj = a; | |
// Create constructor using: | |
// | |
// * `constructor` property of object, if set | |
// * OR patch in parent constructor if a parent has been passed in | |
// * OR use an empty function if no parent is assigned. | |
child = ( | |
obj.hasOwnProperty('constructor') ? | |
obj.constructor : | |
( | |
parent ? | |
function () { | |
parent.prototype.constructor.apply(this, arguments); | |
} : | |
function () {} | |
) | |
); | |
// Make a prototype bridge between child and parent. | |
parent && __bridge(child, parent); | |
// Assign properties in our object literal to the prototype of our | |
// new constructor. This will also override properties inherited | |
// from the parent prototype. | |
__merge(child.prototype, obj); | |
return child; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Another take on Classical inheritance in JS. The goals for this snippet are:
__merge
,__bridge
).