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']);
});