Skip to content

Instantly share code, notes, and snippets.

@saksmt
Created February 26, 2015 22:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saksmt/020e5f62e819a81f018e to your computer and use it in GitHub Desktop.
Save saksmt/020e5f62e819a81f018e to your computer and use it in GitHub Desktop.
Extension for JavaScript providing object oriented feature
(function (global) {
'use strict';
/**
* @return {Function} Abstract function placeholder
*/
Function.prototype.makeAbstract = function () {
return function () {
throw new Error('Abstract method can\'t be called.');
};
};
/**
* Factory method to create abstract methods.
* @returns {Function}
*/
Function.abstractMethod = function () {
var method = function () {};
return method.makeAbstract();
};
/**
* Check if protected-data was injected
* @returns {boolean}
*/
Function.prototype.isProtectedInjected = function () {
return false;
};
/**
* Inject protected-data object to class
* @private
* @param Class {Function} Class
* @param protectedData {Object} Protected-data object
* @return {Function} Result class
*/
function injectProtected(Class, protectedData) {
return (function (Native) {
function Overridden() {
var args = Array.prototype.map.call(arguments, function (value) { return [value]; });
args.unshift(protectedData);
args.unshift(null);
return (new (Function.prototype.bind.apply(Native, args))());
}
Overridden.prototype = new Native({});
Overridden.getNative = function () {
return Native;
};
Overridden.isProtectedInjected = function () {
return true;
};
return Overridden;
}(Class));
}
/**
* Get native class without injection of protected
* @returns {Function} Class
*/
Function.prototype.getNative = function () {
return this;
};
/**
* Extend from @a ParentClass
* @param {Function} ParentClass
* @return {Function} Result class
*/
Function.prototype.extend = function (ParentClass) {
var protectedData = {},
parent,
me = this.getNative();
if (ParentClass.isProtectedInjected()) {
ParentClass = injectProtected(ParentClass.getNative(), protectedData);
}
parent = new ParentClass();
me.prototype = parent;
me.prototype.constructor = me;
protectedData.parent = parent;
if (me.isProtectedInjected()) {
me = injectProtected(me, protectedData);
}
me.prototype = parent;
me.prototype.constructor = me;
return me;
};
/**
* Injects protected-data object to class
* @example
* function SomeClass(protectedData/\* , ... *\/) {
* protectedData.protectedMethod = function () {};
* protectedData.protectedVariable = 'Access only from children and self';
* /\* ...Realization... *\/
* }.injectProtected()
* @returns {Function}
*/
Function.prototype.injectProtected = function () {
return injectProtected(this, {});
};
global.objectOriendedExtension = true;
}(Function, global));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment