JS: Early and Late Binding

Adapted from http://javascript.info/tutorial/binding

by dimadima

HTML

<div id="box"></div>

CSS

body {
    background-color: black;
}
#box {
    width: 125px;
    height: 125px;
    background-color: navy;
}

JavaScript

var bindNow = function (func, context) {
    var bindsNow = function () {
        // The function is passed directly for binding
        return func.apply(context, arguments);
    };
    return bindsNow;
};

var bindLater = function (funcName, context) {
    var bindsLater = function () {
        // A string is used to get the function from its context
        return context[funcName].apply(context, arguments);
    };
    return bindsLater;
};

function OrangeBox($elem) {
    // `this` is `NavyBox`, since `OrangeBox` was invoked with `apply()` 
    // and the context passed was `NavyBox`. So, here we are adding 
    // the `setColor` attribute to `NavyBox`. Had this function not been 
    // invoked via `apply()`, `this` would be `Window`.
    this.setColor = function () {
        $elem.css('background-color', 'orange');
    };

    // Regardless of which object `setColor` is bound to, we pass it for 
    // immediate binding. At this point in execution, `this.setColor` is the
    // function that sets an element's `background-color` to `orange`.
    $elem.on('mouseenter', bindNow(this.setColor, this));
    $elem.on('mouseleave', bindLater('setColor', this));
}

function NavyBox($elem) {
    // `NavyBox` was called with `new`, so `this` is `NavyBox`. 
    // `arguments` is `[$elem]`
    OrangeBox.apply(this, arguments); // 

    this.setColor = function () {
        $elem.css('background-color', 'navy');
    };
}

// Calling a function with the `new` keyword binds that Function object 
// to `this` at runtime.
navy_box = new NavyBox($('#box'));