Created
November 28, 2012 20:32
-
-
Save markandrus/4164145 to your computer and use it in GitHub Desktop.
Variable Scoping in JavaScript: A counter-intuitive example?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* 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