(function(){})() : javaScript closure and self executing function

One of the most useful applications of executed anonymous functions is the ability to solve a nasty issue
with loops and closures. Listing 3-19 has a common piece of problematic code:
Listing 3-19: A problematic piece of code in which the iterator is not maintained in the closure.
<div></div>
<div></div>
<script>
var div = document.getElementsByTagName(“div”);
for ( var i = 0; i < div.length; i++ ) {
div[i].addEventListener(“click”, function(){
alert( “div #” + i + ” was clicked.” );
}, false);
}
</script>
In Listing 3-19 we encounter a common issue with closures and looping, namely that the variable that’s
being enclosed (i) is being updated after the function is bound. This means that every bound function
handler will always alert the last value stored in i (in this case, ‘2’). This is due to the fact that closures
only remember references to variables – not their actual values at the time at which they were called. This
is an important distinction and one that trips up a lot of people.
Not to fear, though, as we can combat this closure craziness with another closure, like in Listing 3-20.
Listing 3-20: Using an anonymous function wrapper to persist the iterator properly.
<div></div>
<div></div>
<script>
var div = document.getElementsByTagName(“div”);
for ( var i = 0; i < div.length; i++ ) (function(i){
div[i].addEventListener(“click”, function(){
alert( “div #” + i + ” was clicked.” );
}, false);
})(i);
</script>
Using this executed anonymous function as a wrapper for the for loop (replacing the existing {…}
braces) we can now enforce that the correct value will be enclosed by these handlers. Note that, in order to
achieve this, we pass in the iterator value to the anonymous function and then re-declare it in the arguments.
This means that within the scope of each step of the for loop the i variable is defined anew, giving our
click handler closure the value that it expects.

(Secrets of the JavaScript Ninja)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s