Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Strange Scoping Problem

0 views
Skip to first unread message

shaneal

unread,
Feb 17, 2008, 3:29:58 AM2/17/08
to
Hello all,

I've been trying to learn some javascript and I ran into a strange
scoping problem I was hoping someone here could help with. I have a
fair amount of experience with functional programming, but very little
with javascript, so please excuse the unidiomatic code.

When I do:

var functions = new Array();

function printNum(x) {
alert(x);
}

for(var i=0;i<5;i++) {
functions[i] = function() { printNum(i);}
}

Now, I'd not expect
functions[0]();
to alert with 0, but instead it alerts with 5. Why is that, and how
can I work around it?

I was banging my head on a strange problem for a bit, until I finally
managed to track down the problem to something isomorphic to this bit
of code.

PS: functions[1-4](); all alert with 5 too ... in case that is
relevant

Thanks for the help, and I apologize in advance for any breaches of
protocol I've made here (first time on comp.lang.javascript).

David Mark

unread,
Feb 17, 2008, 3:46:58 AM2/17/08
to
On Feb 17, 3:29 am, shaneal <sma...@gmail.com> wrote:
> Hello all,
>
> I've been trying to learn some javascript and I ran into a strange
> scoping problem I was hoping someone here could help with. I have a
> fair amount of experience with functional programming, but very little
> with javascript, so please excuse the unidiomatic code.
>
> When I do:
>
> var functions = new Array();
>
> function printNum(x) {
>    alert(x);
>
> }
>
> for(var i=0;i<5;i++) {
>    functions[i] = function() { printNum(i);}
>
> }
>
> Now, I'd not expect
> functions[0]();
> to alert with 0, but instead it alerts with 5. Why is that, and how
> can I work around it?

Because i *is* 5 after the loop is finished. All of the functions
created are referencing the same i variable. If the for loop is run
in the global context, then i is a global variable. If not, i is a
local variable and part of a closure formed by assigning references to
the functions to the global functions array.

Something like this will produce the desired results:

functions[i] = (function(j) { return function() { printNum(j); }; })
(i);

That pattern creates a distinct closure for each of the five
functions.

>
> I was banging my head on a strange problem for a bit, until I finally

Scope-related issues (particularly closures) are a common source of
confusion for beginning JS programmers.

[snip]

shaneal

unread,
Feb 17, 2008, 5:11:37 AM2/17/08
to
ah, many thanks. your explanations make perfect sense.
0 new messages