Skip to content

Instantly share code, notes, and snippets.

@markandrus
Created November 28, 2012 20:32
Show Gist options
  • Select an option

  • Save markandrus/4164145 to your computer and use it in GitHub Desktop.

Select an option

Save markandrus/4164145 to your computer and use it in GitHub Desktop.
Variable Scoping in JavaScript: A counter-intuitive example?
/* Variable Scoping in JavaScript: A counter-intuitive example? */
// Initally empty list of functions
fs = [];
// Populate `fs` with functions.
for (var i=0; i<10; i++) {
fs.push(function() {
console.log(i);
});
}
// Now call each function in `fs`.
fs.map(function(f) {
f();
});
/* What gets logged to the console?
10
10
10
...
10
Seems counter-intuitive, but this is how variable scoping in JavaScript works.
The `i` on line 9 is not bound until its enclosing function is called on line
15, and at this point in time, `i` equals 10.
We need to bind `i` earlier by creating a closure. */
fs = [];
for (var i=0; i<10; i++) {
fs.push(function (j) {
return function() {
console.log(j);
};
}(i));
}
fs.map(function(f) {
f();
});
/* Notice that we wrapped the original `function() { console.log(j); }` code in
an additional layer:
function(j) {
...
}(i);
This function takes an argument `j`, passing it to any code in the
function body (...), and immediately invokes itself with input `i`. Some
people call this an Immediately-Invoked Function Expression (or IIFE).
Invoking this function binds `j` to the value of `i` during the current
iteration of the `for`-loop.
Now we get:
1
2
3
...
9
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment