Nested Inheritance with composition

Use composition and inheritance to augment the nesting upward and downward.

by gschutz

HTML

<script src="https://cdn.rawgit.com/lodash/lodash/3.10.1/lodash.js"></script>

JavaScript

(function(exports){
    'use strict';
    
    function $extendFirst(source) {
        this.$extend = function(name, ctr) {
            function nw() {
                var nv;
                if (typeof ctr == "function") {
                    ctr.prototype.$parent = this;
                    nv = new (Function.prototype.bind.apply(ctr, [ctr].concat(_.toArray(arguments))));
                } else if(_.isPlainObject(ctr)) {
                    // assign by reference, not copy
                    ctr.$parent = this;
                    nv = ctr;
                }
                nv.$parent = this;
                return nv;
            }

            $extendFirst.call(nw, ctr);
            nw.constructor = ctr;

            this[name] = nw;
            
            if (typeof ctr == "function") {
            	source.prototype[_.capitalize(name)] = nw;
            } else if(_.isPlainObject(ctr)) {
            	source.prototype[name.toLowerCase()] = nw;
            }
        }
    }
    
    function Neomap(options, config) {
        _.defaultsDeep(config || {}, {
            color: "red"
        });
        this.$config = config;
    }
    
    function neomap(a,b,c,d) {
        return new Neomap(a,b,c,d);
    }
    
    //neomap.$extend = $extend.bind(Neomap); 
	$extendFirst.call(neomap, Neomap);
    
    neomap.constructor = Neomap;
    
    exports.Neomap = neomap;
}(window));

(function() {
    'use strict';
    
    function Builder() {
        this.type = "wall";
        
        console.log(this);
    }
    
    Neomap.$extend('Builder', Builder);
}());

(function() {
    'use strict';
    
    function Wall() {
        this.height = 12;
    }
    
    Neomap.Builder.$extend('Wall', Wall);
    
    Neomap.$extend('helper', {
        instance: {}
    });
}());

(function() {
    'use strict';
    
    var n = Neomap({}, {color: "black"});
    
    var builder = n.Builder();
    
    console.log(n instanceof Neomap.constructor);
    console.log(builder...