Closure is a procedure or a function, which body contains links to the variables, declared out of the function body but not as parameters of this function (but in the surrounding code).
Closures can be the reason of the memory leak.
The article contains most frequent cases of the closures use and the ways of their elimination:
var oval = document.getElementById("div");
if (oval.addEventListener)
oval.addEventListener("onclick", function (event)
{
//You can work with oval from here
}, false);
else
oval.attachEvent("onclick", function (event)
{
//You can work with oval from here
});
Often, the closure is used to get access to the dom node the event is attached to.
function onclick(event)
{
this === oval
}
function test()
{
var oval = document.getElementById("div");
if (oval.addEventListener)
oval.addEventListener("onclick", onclick, false);
else
oval.onclick = onclick;
}
The specific is that the attachEvent function is no longer used, and the onclick property/event is used instead. It is required for this context in the event handler to be equal to the dom element with the attached event.
var oval = document.getElementById("div");
setTimeout(function()
{
oval.innerHTML = "ok";
}, 100);
function test(oval)
{
oval.innerHTML = "ok";
}
setTimeout(test, 100, oval);
However, this code is not functional in the IE, because the test function in IE is always called without parameters. That is why the following function is used instead of the built-in one:
PP = {};
PP.IsIE = navigator.userAgent.indexOf(' MSIE ') > -1;
PP._onSetTimeout = function(index)
{
var callback = PP._onSetTimeout.tims[index];
delete PP._onSetTimeout.tims[index];
return callback.Handler.call(this, callback.Params);
};
PP._onSetTimeout.tims = [];
PP.setTimeout = function (func, delay, params)
{
if (PP.IsIE && typeof(params) != 'undefined')
{
var i = PP._onSetTimeout.tims.push({ Handler : func, Params : params}) - 1;
return setTimeout("PP._onSetTimeout(" + i+ ")", delay);
}
else return setTimeout(func, delay, params);
};
var XHR = window.XMLHttpRequest ? new window.XMLHttpRequest() : new window.ActiveXObject("Microsoft.XMLHTTP");
XHR.onreadystatechange = function()
{
if (XHR.status == 200)
alert(XHR.responseText); //Here it is comfortable to use link to the XHR and call the required callbacks
};
function onreadystatechange()
{
if (this.status == 200) //this – is always XMLHttpRequest
alert(this.responseText);
};
var XHR = window.XMLHttpRequest ? new window.XMLHttpRequest() : new window.ActiveXObject("Microsoft.XMLHTTP");
XHR.onreadystatechange = onreadystatechange;
See also: