mindfullsilence
3/19/2016 - 5:12 PM

Simple Javascript Class Extension Factory

Simple Javascript Class Extension Factory



Zion.Component = Zion().extend({
    constructor: function() {},
    method1: function() {}
});

Zion.Component.Slider = Zion().extend('Component', {
    constructor: function() {},
    method2: function() {this.x = 'no';},
    method3: function() {}
});

Zion.Component.Slider.Slide = Zion().extend('Component', 'Slider', {
    method2: function() {
        this.x = 'yes';
        // override parent method here
        // optionally call parent method
        this.parent.method2.call(this);
        console.log(this.x);
    }
})

Zion.Component.Dropdown = Zion().extend('Component', {
    method2: function() {},
    method3: function() {}
});

var component = new Zion.Component();
var slider = new Zion.Component.Slider();
var slide = new Zion.Component.Slider.Slide();
var dropdown = new Zion.Component.Dropdown();

var instance = function(varname, classname, variable, klass) {
    var message = varname;
    message += ' is an instance of ' +
        classname +
        '? ' +
        (variable instanceof klass);
    console.log(message);
}

instance('component', 'Zion', component, Zion);
instance('component', 'Zion.Component', component, Zion.Component);
instance('component', 'Zion.Component.Slider', component, Zion.Component.Slider);
instance('component', 'Zion.Component.Slider.Slide', component, Zion.Component.Slider.Slide);
instance('component', 'Zion.Component.Dropdown', component, Zion.Component.Dropdown);
instance('slider', 'Zion', slider, Zion);
instance('slider', 'Zion.Component', slider, Zion.Component);
instance('slider', 'Zion.Component.Slider', slider, Zion.Component.Slider);
instance('slider', 'Zion.Component.Slider.Slide', slider, Zion.Component.Slider.Slide);
instance('slider', 'Zion.Component.Dropdown', slider, Zion.Component.Dropdown);
instance('slide', 'Zion', slide, Zion);
instance('slide', 'Zion.Component', slide, Zion.Component);
instance('slide', 'Zion.Component.Slider', slide, Zion.Component.Slider);
instance('slide', 'Zion.Component.Slider.Slide', slide, Zion.Component.Slider.Slide);
instance('slide', 'Zion.Component.Dropdown', slide, Zion.Component.Dropdown);
instance('dropdown', 'Zion', dropdown, Zion);
instance('dropdown', 'Zion.Component', dropdown, Zion.Component);
instance('dropdown', 'Zion.Component.Slider', dropdown, Zion.Component.Slider);
instance('dropdown', 'Zion.Component.Slider.Slide', dropdown, Zion.Component.Slider.Slide);
instance('dropdown', 'Zion.Component.Dropdown', dropdown, Zion.Component.Dropdown);
var Zion = function() {
    var ret;
    if(this instanceof Window) {
        ret = new Zion();
    }
    else ret = this;
    return ret
};

Zion.prototype.extend = function() {
    var undef;
    var self = this;
    var args = [].slice.call(arguments);
    var prototype = args.pop();
    var parent = function(args) {
        var parent = Zion;
        var obj;
        while(obj = args.shift()) {
            parent = parent[obj];
        }
        return parent;
    }(args);
    var klass = function Class() {
        if(prototype.constructor !== undef) {
            prototype.constructor.apply(this);
        }
        parent.apply(this);
        return this;
    }

    klass.prototype = Object.create(parent.prototype);
    klass.prototype.constructor = klass;

    for(var method in prototype) {
        if(prototype.hasOwnProperty(method)) {
            klass.prototype[method] = prototype[method];
        }
    }

    klass.prototype.Parent = parent;
    klass.prototype.parent = new klass.prototype.Parent();

    return klass;
}