Hey Rahul, in JavaScript (unlike most languages) variable scopes are only
created by functions. That means that loops (like your for loop) don't
create their own scopes.

In your example:

function buildList(list) {
  var arrFun = new Array();
  for(var x = 0; x < list.length; x++) {
    arrFun[x] = function() {
      alert(" NUMBER "+list[x]);
    } // end anonymous function scope
  }
  return arrFun;
} // end buildList scope

I've colored the variables in each scope (red for the scope of the buildList
function and green for the anonymous functions you are assigning to arrFun.
Or to put it in a list:

buildList
---------
list
arrFun
x

Anonymous function
------------------
[empty]

There are no variables in the anonymous function's scope because it has no
arguments and doesn't use the "var" keyword anywhere. When it refers to x,
it's referring to the x in buildList's scope (I think you get this part;
that's what a closure is).

However, since x is not scoped to each loop of the for loop, but instead to
the entire buildList function, it gets incremented each time the loop runs.
By the time you call any of the functions in arrFun (long after the for loop
has finished), x has been incremented all the way up to 3 by the for loop.
Since list[3] is undefined, that's what you get.

Both Poetro and Ultranaut's solutions use an additional function with a
single variable in it to create a new scope that captures the value of x on
each iteration of the loop instead of accessing x directly (since the value
of x keeps changing).

-Rob


On Sun, Oct 23, 2011 at 7:33 AM, Rahul <[email protected]> wrote:

> hi,
>
> i didnt understood this ,
>
> " The value x is out of bonds by the time you call the functions. So
> x
> is a closure variable, and the value of it is list.length+1 by the
> time the function finished executing. "
>
> the variable x is declared in first for-loop, so its scope is just for
> the loop.
> from my understanding array arrFun holds a function at index 0,1,2
> each.
>
> now when i call  function buildList() from fn27(), the buildList
> returns array of functions as mentioned above,
>
> now if i iterate the array arr using variable x, this x has nothing to
> do with the x declared in the for-loop of function buildList for array
> creation arrFun,
>
> now what i expect is arr should be iterated using x from 0,1,2.
> and arr should be holding fn0, fn1, fn2
>
> so can you please clear my confusion, were i am going wrong.
>
> On Oct 21, 7:45 pm, Poetro <[email protected]> wrote:
> > 2011/10/21 Rahul <[email protected]>:
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > > function buildList(list){
> > >        var arrFun = new Array();
> > >        for(var x = 0; x < list.length; x++){
>               arrFun[x] = function()
> > > { alert(" NUMBER "+list[x]); }
> > >        }
> > >        return arrFun;
> > > }
> >
> > > function fn27(){
> > >        var arr = buildList([23,45,67]);
> > >        for(var x = 0; x < arr.length; x++){
> > >        arr[x]();
> > >        }
> > > }
> >
> > > window.onload = fn27();
> >
> > > here, on page onload there is a three times alert as "NUMBER
> > > undefined",
> > > why so ?
> > > why list[x] is not holding the value which was assigned initially.
> >
> > > waiting for the reply
> >
> > The value x is out of bonds by the time you call the functions. So x
> > is a closure variable, and the value of it is list.length+1 by the
> > time the function finished executing. This gives you an undefined
> > value, as there is no defined value for that index in the array. There
> > are several ways to fix that.
> >
> > function buildList(list) {
> >   var arrFun = [];
> >   function callback(y) {
> >     // y is a closure variable
> >     return function() {
> >       alert(" NUMBER " + list[y]);
> >     };
> >   }
> >   for (var x = 0; x < list.length; x++) {
> >     arrFun[x] = callback(x);
> >   }
> >   return arrFun;
> >
> > }
> >
> > --
> > Poetro
>
> --
> To view archived discussions from the original JSMentors Mailman list:
> http://www.mail-archive.com/[email protected]/
>
> To search via a non-Google archive, visit here:
> http://www.mail-archive.com/[email protected]/
>
> To unsubscribe from this group, send email to
> [email protected]
>

-- 
To view archived discussions from the original JSMentors Mailman list: 
http://www.mail-archive.com/[email protected]/

To search via a non-Google archive, visit here: 
http://www.mail-archive.com/[email protected]/

To unsubscribe from this group, send email to
[email protected]

Reply via email to