Losing this context inside a closure (module)

The use of $.each causes this context to change back to the global context (window). Despite efforts, like using self, calling sub functions always revert the context thereafter.

by Chris Walsh

HTML

<pre id='log'></pre>

CSS

body { 
    font-family: verdana, Arial, sans-serif;
}

JavaScript

var MYMODULE = (function ($, document) {
    var my = {};
    my.init = function(fruit) {
        var self = this;
		$.each(fruit, function (idx, fr) {
            log('--- '+fr+' ---');
            log('Inside $.each. this='+this+'; self='+self);
            
            // Note: The 'this' context at this point is no longer the MYMODULE closure
            log('Calling initFruit directly...');
			initFruit(fr);
            
            // The 'self' variable however is still 'in scope' so I try doing calling initFruit() using
            // .call in order to change the object context, however, the sub function initFruitSub() still
            // shows this as the window object and so I can no longer access private variables in MYMODULE
            log('Calling initFruit using .call(self) ...');
            initFruit.call(self, fr);
		});

    };
    
    function initFruit(fr) {
        log('initFruit('+fr+'); this='+this);
        if(this === window)
            return;
        
        // *** FAIL! this context is no longer module ****
        // I want to interact with variables in the MYMODULE context (e.g. 'mycache')
        // but cannot by default.
        initFruitSub(fr);
    }
    
    function initFruitSub(fr) {
        log('initFruitSub('+fr+'); this='+this);
        
        // Even though efforts were made to call initFruit with the MYMODULE context,
        // calling a subfunction like this one still reverts this back to window
    }
    
    
    return my;    
}(jQuery, document));


function log(s) {
    $('#log').append($(document.createElement('div')).text(s));
}


$(document).ready(function () {
    MYMODULE.init(['apples','bananas','pears']);
});