views:

52

answers:

2

Example:

var o = {};
for(var i = 0; i < 5; i++) {
  o[i] = function () {
      console.log(i);
  };
}

o[3]();

When I call o3, it will always display 5 on the console, even if I call o0, o4, or any one of those. It will always display 5 because that's the last value i had. How do I make it display the value of i when the anonymous function is made? As in o3 should display 3 in the console.

+1  A: 
o[i] = (function (i) {
    return function () { console.log(i); }
})(i);
deceze
+4  A: 

You should do:

var o = {};
for(var i = 0; i < 5; i++) {
  (function(i) { // <- self-executing anonymus function with a parameter i
    o[i] = function () {
        console.log(i); // <- i here will be the argument i, 
                        //    not the i from the loop
    };
  })(i); // <- pass i as an argument
}

o[3]();

What happens is that you create something called closure so as to keep the state of i.

Closure means that an inner function keeps a reference to the outer function and so gains access to its variables and parameters (even after the outer function has returned).

A trivial example for closure is:

function outer(arg) { 
  var variable = 5;
  arg = 2;
  function inner() {
    alert(variable);  // <- the inner function has access to the variables
    alert(arg);       //     and parameters of the outer function
  }
}

A self-executing (self-invoking, or immediate) function is a function that is called right after it is declared.

(function() {
  alert("executed immediately");
})();

The combination of both and the fact that only functions have scope in Javascript, leads you to the technique mentioned above to create a scope with a new function which keeps the state of i, which would otherwise be changed by the inner function because of closure.

galambalazs
Thank you this worked.
this is a dead end