Class Factory

by plus5keen

HTML

<div class="output">
    Output:<br/>
</div>

JavaScript

var classUtils = (function () {
    'use strict';

    var superMethodRegex = /xyz/.test(function () { var xyz; return xyz; }) ? /\b_super\b/ : /./;
    var processMethods = function (Class, methods) {
        var proto = Class.prototype;
        // inspired by Simple JavaScript Inheritance by John Resig
        _.each(methods, function (method, key) {
            var _super = proto[key];
            if (
                typeof method === 'function' &&
                typeof _super === 'function' &&
                superMethodRegex.test(method)
            ) {
                proto[key] = function () {
                    var temp = this._super;
                    this._super = _super;

                    var result;
                    try {
                        result = method.apply(this, arguments);
                    } finally {
                        this._super = temp;
                    }

                    return result;
                };
            } else {
                proto[key] = method;
            }
        });
    };

    var initMode = true;
    var createClassFactory = function (classFactoryOptions) {
        var DefaultBase = classFactoryOptions.BaseClass || Object;
        var instanceProcessors = classFactoryOptions.instanceProcessors;
        var classProcessors = classFactoryOptions.classProcessors;

        return function (classOptions) {
            var Base = classOptions.BaseClass || DefaultBase;

            var buildBase = Base._build;
            var buildThis = classOptions.build; // can only be extended, never overridden
            var build = function (instance) {
                if (buildBase) { buildBase(instance); }
                if (buildThis) { buildThis(instance); }
                _.each(instanceProcessors, function (instanceProcessor, key) {
                    var options = classOptions[key];
                    if (options) {
                        instanceProcessor(instance, options);
                ...