Created
April 11, 2011 14:46
-
-
Save JamieMason/913628 to your computer and use it in GitHub Desktop.
Proof of concept to extend objects and maintain protected data
This file contains 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
// A simple class creation library. | |
// Inspired by base2 and Prototype | |
(function(){ | |
var initializing = false, | |
// Determine if functions can be serialized | |
fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; | |
// Create a new Class that inherits from this class | |
Object.subClass = function(prop) { | |
var _super = this.prototype; | |
// Instantiate a base class (but only create the instance, | |
// don't run the init constructor) | |
initializing = true; | |
var proto = new this(); | |
initializing = false; | |
// Copy the properties over onto the new prototype | |
for (var name in prop) { | |
// Check if we're overwriting an existing function | |
proto[name] = typeof prop[name] == "function" && | |
typeof _super[name] == "function" && fnTest.test(prop[name]) ? | |
(function(name, fn){ | |
return function() { | |
var tmp = this._super; | |
// Add a new ._super() method that is the same method | |
// but on the super-class | |
this._super = _super[name]; | |
// The method only need to be bound temporarily, so we | |
// remove it when we're done executing | |
var ret = fn.apply(this, arguments); | |
this._super = tmp; | |
return ret; | |
}; | |
})(name, prop[name]) : | |
prop[name]; | |
} | |
// The dummy class constructor | |
function Class() { | |
// All construction is actually done in the init method | |
if ( !initializing && this.init ) | |
this.init.apply(this, arguments); | |
} | |
// Populate our constructed prototype object | |
Class.prototype = proto; | |
// Enforce the constructor to be what we expect | |
Class.constructor = Class; | |
// And make this class extendable | |
Class.subClass = arguments.callee; | |
return Class; | |
}; | |
})(); | |
function curry (fn /*, ... */) | |
{ | |
var aCurryArgs = Array.prototype.slice.call(arguments, 1); | |
return function ( /* ... */ ) | |
{ | |
var aCalleeArgs = Array.prototype.slice.call(arguments, 0), | |
aMergedArgs = aCurryArgs.concat(aCalleeArgs); | |
return fn.apply(this, aMergedArgs); | |
}; | |
}; | |
// ######################################################### | |
var Sup = Object.subClass({ | |
echo: function(oProtected, sComment){ | |
alert('Sup:' + oProtected.secret + ' ' + sComment); | |
} | |
}); | |
var Sub = Sup.subClass({ | |
echo: function(oProtected, sComment){ | |
this._super(oProtected, sComment); | |
alert('Sub:' + oProtected.secret + ' ' + sComment); | |
} | |
}); | |
function createSub(){ | |
var oInstance = new Sub(), oProtected = { | |
secret: 'Hello World' | |
}; | |
// bind the protected data with the original method | |
for (var prop in oInstance) { | |
if (typeof oInstance[prop] === 'function') { | |
oInstance[prop] = SKY.utils.curry(oInstance[prop], oProtected); | |
} | |
} | |
return oInstance; | |
} | |
createSub().echo('MOOOOOMIN'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment