JavaScript's Infamous Loop Issue Solved with Closure
Consider the following code intended to generate five links with unique alert events to display their respective IDs:
function addLinks() { for (var i=0, link; i<5; i++) { link = document.createElement("a"); link.innerHTML = "Link " + i; link.onclick = function () { alert(i); }; document.body.appendChild(link); } }
However, this code fails to achieve its purpose, as clicking any of the links displays "link 5." To remedy this, the following modified code successfully assigns each link its unique ID:
function addLinks() { for (var i=0, link; i<5; i++) { link = document.createElement("a"); link.innerHTML = "Link " + i; link.onclick = function (num) { return function () { alert(num); }; }(i); document.body.appendChild(link); } }
Understanding the Closure Magic
The key to this code's success lies in the concept of closures. In JavaScript, a closure is a function that retains access to the lexical environment of the function in which it was created. In other words, it can access variables and arguments defined in the outer function, regardless of its own scope.
In the first code snippet, the inner function references the variable i, which is hoisted to the top of the function's scope. As the loop iterates, the variable i gets updated, and the inner function always refers to its most recent value. This results in all links displaying "link 5" when clicked.
In the second code snippet, the outer function literal creates a new function object with its own scope and local variable num, whose value is set to the current value of i. The function object is returned as the event handler for the link's onclick event.
Crucially, the inner function is created within the context of the outer function's lexical environment, which includes the variable num. Thus, the inner function has continued access to num and returns a function that alerts the correct ID when the link is clicked.
This approach ensures that each link has its own unique closure, which preserves the correct value of i even after the loop has terminated.
The above is the detailed content of Why Does Using Closures Solve JavaScript's Loop-and-Closure Problem?. For more information, please follow other related articles on the PHP Chinese website!