protected methods and prototypal inheritance

by Ron Valstar

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.min.js"></script>

JavaScript

/**
 * An example of protected methods and prototypal inheritance
 * @requires lodash
 * @param {string} name Call it something
 * @param {object} extend An object with functions to override (a .super() method will be added).
 * @returns {object}
 */
var baseFoo = (function(){
    var basePrototype = {
            protectedMethod: protectedMethod
            ,publicMethod: publicMethod
        }
        ,baseProperties = {}
    ;
    
    function protectedMethod(){
        return 'protectedMethod';
    }
    
    function publicMethod(){
        return 'publicMethod';
    }
    
    return function(name,extend){
        var inst = Object.create(basePrototype,baseProperties);
        _.extend(inst,{
            name: name||'noName'
            //
            ,expose: [] // The property the child object should return (could also be an object or a function).
            ,zuper: {} // Alas, super is reserved
        });
        //
        // create super
        for (var s in basePrototype) {
            if (basePrototype.hasOwnProperty(s)) {
                inst.zuper[s] = inst[s].bind(inst);
            }
        }
        Object.freeze(inst.zuper); // Because we can
        //
        // extend the instance
        if (extend) {
            for (var fncName in extend) {
                if (extend.hasOwnProperty(fncName)) {
                    inst[fncName] = extend[fncName].bind(inst);
                }
            }
        }
        //
        // extend expose property with public methods
        _.extend(inst.expose,{
            publicMethod: inst.publicMethod.bind(inst)
        });
        //
        // (do some more initialisation stuff like adding event listeners)
        //
        return inst;
    }
})();
 
/**
 * Here's a child object
 */
var childFoo = (function(){
    // call the factory method to get an instance
    var inst = baseFoo('childFoo',{
            protectedMethod: protectedMethod
        })
        // add other public methods to the...