Parasitic Inheritance

Exploring simpler syntax for parasitic inheritance.

HTML

<h3>Parasitic Inheritance</h3>
<p>As described by <a href="http://www.crockford.com/javascript/inheritance.html">Crockford</a></p>
<p class="notice-me">Enable console for tests</p>
<p>See this <a href="http://stackoverflow.com/questions/18776989/">Stack Overflow Question</a> for more information.

CSS

.notice-me {
    color:red;
    font-weight:bold;
}

JavaScript

function Parasite(host) {
    var self = {};
    self.host = host;
    self.swollen = false;
    
    self.init = function() {
        console.debug('Parasite.init');
        return self;
    };
    
    self.suck = function() {
        console.log("I'm a parasite who sucks on " + self.host);
        self.swollen = true;
        return self;
    };
    
    self.extend = function(child) {        
        for(var prop in self) {
            if (prop == 'extend') {     // skip extend
                console.debug('skip extend');
                continue;
            }
        
            var is_extended = child.hasOwnProperty(prop);
            var is_accessor = typeof self[prop] != "function";
            
            // inherit prop
            if (! is_extended) {
                child[prop] = self[prop];
                console.debug('prop', prop, 'inherited by child');
            }
            // default: override
            else {
                console.debug('prop', prop, 'overridden by child');
            }
            
            // For accessors, parent should reference child. This tries to
            // synchronize them on the child's accesor.
            if (is_accessor) {
                var accessor = prop.toString();
                console.warn('define accessor for', accessor, ':', child[accessor]);
                Object.defineProperty(self, accessor, {                      
                    get: function() {
                        var val = child[accessor];
                        console.debug('getting', accessor, val, 'from', child, 'for', self);
                        return val;
                    },
                    set: function(val) { 
                        console.debug('setting', accessor, val, 'from', child, 'for', self);
                        child[accessor] = val;
                    },
                    enumerable: true,
                    configurable: true
                });
            };
        }

       ...