classified
Version:
Real OOP for Javascript
20 lines • 6.18 kB
JavaScript
/**
* Classified - Real OOP for Javascript
*
* Adds protected, private, constants, parent(super)
* functionality to regular defined classes.
* In the backend the methods are being hijacked
* creating the extra public properties and destroying them
* after it finishes.
*
* The idea came from http://ejohn.org/blog/simple-javascript-inheritance/
*
* The main quirk is when dealing with async inside the methods. In these cases,
* methods need to be stored statically in order to use it inside of an async
*
* @version 0.1.3
* @author Christian Blanquera <cblanquera@openovate.com>
* @website https://github.com/cblanquera/classified
* @license MIT
*/
!function(){var t={},n=function(){var r="Expecting argument 1 in define() to be an object or return an object.",h="Expecting argument 1 in trait() to be a registry item, an object or return an object.",d=function(){return d.load.apply(d,arguments)},_=!1,y=null,l={definitions:[],traits:[]},g={definitions:[],traits:[]};d.define=function(t){if("object"!=typeof t&&"function"!=typeof t)throw r;return l.definitions.push(t),this},d.definition=function(){var t,n={},e=this.parents();for(t=0;t<e.length;t++)i(c(e[t]),n,!0);for(t=0;t<l.definitions.length;t++)"undefined"==typeof g.definitions[t]&&g.definitions.push("object"==typeof l.definitions[t]?l.definitions[t]:new l.definitions[t]),i(g.definitions[t],n,!0);return n},d.parents=function(){for(var n=[],e=0;e<l.traits.length;e++){if("undefined"==typeof g.traits[e])switch(typeof l.traits[e]){case"object":g.traits.push(l.traits[e]);break;case"string":g.traits.push(t[l.traits[e]].definition());break;case"function":if("undefined"!=typeof l.traits[e].__isClassified__){g.traits.push(l.traits[e].definition());break}g.traits.push(l.traits[e].prototype)}n.push(g.traits[e])}return n},d.trait=function(n){if("object"!=typeof n&&"function"!=typeof n&&("string"!=typeof n||"undefined"==typeof t[n]))throw h;return l.traits.push(n),this},d.extend=function(t){return this.__isClassified__=!0,n().define(t).trait(this)},d.get=function(){for(var t=this.definition(),n=this.parents(),r={method:0,parents:0},c={},h={},d={},_={},y=i(u(t),{},!0),l=0;l<n.length;l++)i(a(n[l]),d,!0),i(p(n[l]),h,!0),i(u(n[l]),_,!0);i(f(t),c,!0),i(a(t),d,!0);for(var g in _)_.hasOwnProperty(g)&&"undefined"!=typeof y[g]&&delete _[g];var b=Object.freeze(s(c)),w={definition:t,protect:d,secret:y,constants:b,parents:h,stack:r,parentSecret:_};for(g in c)if(c.hasOwnProperty(g)){if("function"!=typeof c[g]||o(c[g]))continue;w.key=g,w.callback=c[g],c[g]=e(w)}return v.prototype=c,v},d.load=function(){return y&&_||(y=this.get().load.apply(null,arguments)),y},d.register=function(n){return t[n]=this,this},d.singleton=function(t){return _=t!==!1,this};var v=function(){"function"==typeof this.___construct&&this.___construct.apply(this,arguments)};return v.load=function(){var t=function(){};t.prototype=v.prototype;var n=new t;return"function"==typeof n.___construct&&n.___construct.apply(n,arguments),n},d},e=function(t){var n=t.definition,e=t.protect,i=t.callback,o=t.protect,s=t.secret,f=t.constants,a=t.parents,u=t.stack,c=t.parentSecret;return function(){var t;if(!u.method&&"undefined"==typeof this.___frozen){var p=this;this.___parent={};for(t in a)a.hasOwnProperty(t)&&(this.___parent[t]=r(a[t],p,u,c));for(t in o)o.hasOwnProperty(t)&&(this[t]=o[t]);for(t in s)s.hasOwnProperty(t)&&(this[t]=s[t]);if(!n[e])for(t in c)c.hasOwnProperty(t)&&(this[t]=c[t])}u.method++;for(t in f)f.hasOwnProperty(t)&&(this[t]=f[t]);return this.___freeze=h.bind(this),this.___unfreeze=d.bind(this,o,s,c),results=i.apply(this,arguments),--u.method||"undefined"!=typeof this.___frozen||this.___unfreeze(),results}},r=function(t,n,e,r){return function(){var i;if(!e.parents)for(i in r)r.hasOwnProperty(i)&&(n[i]=r[i]);e.parents++;var o=t.apply(n,arguments);if(!--e.parents)for(i in r)r.hasOwnProperty(i)&&delete n[i];return o}},i=function(t,n,e){for(var r,s=Object.keys(t),f=s.length;f--;)r=s[f],n[r]=t[r],e&&"object"==typeof t[r]&&null!==t[r]&&!o(t[r])?n[r]=i(t[r],{},e):e&&t[r]instanceof Array&&(n[r]=i(t[r],[],e));return n},o=function(t){if(t===Date||t===RegExp||t===Math||t===Array||t===Function||t===JSON||t===String||t===Boolean||t===Number||t instanceof Date||t instanceof RegExp||t instanceof Array||t instanceof String||t instanceof Boolean||t instanceof Number)return!0;if(/\{\s*\[native code\]\s*\}/.test(""+t))return!0;var n=Object.prototype.toString,e=Function.prototype.toString,r=/^\[object .+?Constructor\]$/,i=RegExp("^"+String(n).replace(/[.*+?^${}()|[\]\/\\]/g,"\\$&").replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),o=typeof t;return"function"===o?i.test(e.call(t)):t&&"object"===o&&r.test(n.call(t))||!1},s=function(t){var n={};for(var e in t)t.hasOwnProperty(e)&&/^[A-Z0-9_]+$/.test(e)&&(n[e]=t[e]);return n},f=function(t){var n={};for(var e in t)t.hasOwnProperty(e)&&(/^_[a-zA-Z0-9]/.test(e)||/^__[a-zA-Z0-9]/.test(e)||(n[e]=t[e]));return n},a=function(t){var n={};for(var e in t)t.hasOwnProperty(e)&&/^_[a-zA-Z0-9]/.test(e)&&(n[e]=t[e]);return n},u=function(t){var n={};for(var e in t)t.hasOwnProperty(e)&&/^__[a-zA-Z0-9]/.test(e)&&(n[e]=t[e]);return n},c=function(t){var n={};for(var e in t)t.hasOwnProperty(e)&&(/^__[a-zA-Z0-9]/.test(e)||(n[e]=t[e]));return n},p=function(t){var n={};for(var e in t)t.hasOwnProperty(e)&&(/^__[a-zA-Z0-9]/.test(e)||"function"!=typeof t[e]||(n[e]=t[e]));return n},h=function(){return this.___frozen=!0,this},d=function(t,n,e){delete this.___parent;for(var r in t)t.hasOwnProperty(r)&&(t[r]=this[r],delete this[r]);for(r in n)n.hasOwnProperty(r)&&(n[r]=this[r],delete this[r]);for(r in e)e.hasOwnProperty(r)&&(e[r]=this[r],delete this[r]);return delete this.___freeze,delete this.___unfreeze,delete this.___frozen,this};"object"==typeof module&&module.exports?module.exports=function(t){return t=t||{},n().define(t)}:"function"==typeof define?define(function(){return function(t){return t=t||{},n().define(t)}}):"function"==typeof jQuery&&"function"==typeof jQuery.extend?jQuery.extend({classified:function(t){return t=t||{},n().define(t)}}):"object"==typeof window&&(window.classified=function(t){return t=t||{},n().define(t)})}();