First one
Second one
Third one
Fourth one
No matter which div we click, the content of the 4th div will be fed back. The reason is that the click event of each div forms a closure with the test method, and the click event of each div shares the same closure scope chain. When the event is triggered, the subscript represented by variable i already points to the fourth div. There are several ways to avoid problems caused by closures.
(1) Use this to convert the scope chain context of the closure. The closure in the above example can be rewritten as: for (var i = 0; i {
var div = els[i];
div.onclick = function()
{
alert(this.innerHTML);
return false;
}
}
When the event of clicking the div is triggered, the search scope is already the context specified by "this". Although the event is still within the "test" closure, since the context of the closure is not accessed or used, there is no problem caused by variables in the closure scope being referenced.
(2) Make the event of clicking the div form a closure with the for loop, so that the variable div in the for loop will not be recycled. For example:
//Define closure method in for loop for (var i = 0; i {
var div = els[i];
a(div);
function a(o)
{
o.onclick = function()
{
alert(o.innerHTML);
}
}
}
//Define closure method outside the for loop for (var i = 0; i {
var div = els[i];
a(div);
}
function a(o)
{
o.onclick = function()
{
alert(o.innerHTML);
}
}
//Use anonymous methods, the principle is similar to the definition in for loop for (var i = 0; i {
var div = els [i];
(function(o)
{
o.onclick = function()
{
alert(o.innerHTML);
}
})( div);
}
Use intermediate method a or anonymous method to create a closure between the for loop body and the onclick event.
(3) Control the scope of variables so that the variables required for the event of clicking the div have nothing to do with the outer scope. For example: for (var i = 0; i {
(function()
{
var div = els[i];
div .onclick = function()
{
alert(div.innerHTML);
}
})();
} <script> <BR>function test() <BR>{ <BR>var els = document.getElementById("test").getElementsByTagName("div"); <BR>for (var i = 0; i < els.length; i++) <BR>{ <BR>var div = els[i]; <BR>div.onclick = function() <BR>{ <BR>alert(div.innerHTML); <BR>return false; <BR>} <BR>} <BR>} <BR>test(); <BR></script>Inner functions themselves may also have inner functions. Each time the scope chain is nested, a new active object is added that is caused by the execution environment that created the inner function object. The ECMA262 specification requires that scope chains be temporary, but there is no limit on the length of the scope chain. The unspoken rule of closure is the relationship between the interaction domain chain context environment between Function and internally defined Function. If used correctly, the potential of nested inner functions is beyond our imagination.