[Javascript] Help with closures

Bill Moseley moseley at hank.org
Fri Jan 12 13:42:18 CST 2007


On Fri, Jan 12, 2007 at 10:33:41AM -0500, Roger Roelofs wrote:
> Here are a couple of links that explain closures in more depth.

Thanks!

> http://blog.morrisjohns.com/javascript_closures_for_dummies

Oh that stinks.  I forgot about example 5 on that page and that it
differs from closures in other languages.

Example 5 on that page shows the problem:

    function buildList(list) {
      var result = [];
      for (var i = 0; i < list.length; i++) {
        var item = 'item' + list[i];    // <<---------- HERE
        result.push( function() {alert(item + ' ' + list[i])} );
      }
      return result;
    }

    function testList() {
      var fnlist = buildList([1,2,3]);
      // using j only to help prevent confusion - could use i
      for (var j = 0; j < fnlist.length; j++) {
        fnlist[j]();
      }
    }

I expected "item" to be a new variable every time through the loop.
Isn't that what "var" means?

        var item = 'item' + list[i];

Yet, running the code "item" refers always to the last value, as shown
in "Example 5".  It returns "item3" three times.

Now, here's that same thing in Perl (not that anyone would write Perl
like this):

    sub buildList {
        my @list = @_;

        my @result;

        for ( my $i = 0; $i < @list; $i++ ) {
            my $item =  'item' . $list[$i];

            push @result, sub { warn "$item  $list[$i]\n" };
        }
        return @result;
    }

    sub testList {
        my @fnlist = buildList( 1,2,3 );
        for ( my $j = 0; $j < @fnlist; $j++ ) {
            $fnlist[$j]->();
        }
    }

    testList();


And running generates this:

    $ perl closure.pl
    item1  
    item2  
    item3

So "$item" in this case is new each time through the loop.  It's local
to the instance of that block of code each time through the loop.



-- 
Bill Moseley
moseley at hank.org




More information about the Javascript mailing list