Lexical scope for closures in JavaScript

Ayende has a post on working with closures in JavaScript. Basically, when looking at capturing variables in a closure, you need to be careful with lexical scope. In JS the scope is a function, so if you want to capture a variable that will change values during the scope of the function, you will need to reference it via another function.

From Ayende’s example, where i is set in a loop, this:

if( nums[i] % 2 == 0)
    {
      var tmpNum = nums[i];
      alertLink.onclick = function() { alert('EVEN: '+ tmpNum ); };
      //tmpNum will be bound to its value when the loop exits.
    } ...

Needs to become this:

if( nums[i] % 2 == 0)
    {
      var act = function(tmpEVEN)
      {
        alertLink.onclick = function() { alert('EVEN: '+tmpEVEN); };
      };
      act(nums[i]);
      //tmpEVEN will be bound to nums[i] at the point where act(nums[i]) is called.
    } ...

Ayende notes that in C#, the first example will work as its lexical scope is the current block (I think :S). In JavaScript, we need to use a function to get the correct scope.

Comments