Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #18928 > unrolled thread

Defining two functions in a loop referring to variables scoped in the loop behave as their were global variables

Started bypwellner@gmail.com
First post2013-03-18 05:29 -0700
Last post2013-03-19 12:25 -0500
Articles 5 — 4 participants

Back to article view | Back to comp.lang.javascript


Contents

  Defining two functions in a loop referring to variables scoped in the loop behave as their were global variables pwellner@gmail.com - 2013-03-18 05:29 -0700
    Re: Defining two functions in a loop referring to variables scoped in the loop behave as their were global variables Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2013-03-18 17:44 +0100
    Re: Defining two functions in a loop referring to variables scoped in the loop behave as their were global variables Gregor Kofler <usenet@gregorkofler.com> - 2013-03-18 18:04 +0100
    Re: Defining two functions in a loop referring to variables scoped in the loop behave as their were global variables Jim T. <x@y.z> - 2013-03-19 12:01 -0500
      Re: Defining two functions in a loop referring to variables scoped in the loop behave as their were global variables Jim T. <x@y.z> - 2013-03-19 12:25 -0500

#18928 — Defining two functions in a loop referring to variables scoped in the loop behave as their were global variables

Frompwellner@gmail.com
Date2013-03-18 05:29 -0700
SubjectDefining two functions in a loop referring to variables scoped in the loop behave as their were global variables
Message-ID<3e54afae-ea56-43c0-95d8-e6a173d8c1a6@googlegroups.com>
I have a mysterious problem in my JavaScript which is -- or seems to be -- in the nature of JavaScript itself, but I don't find the reason why and I don't have any idea of how to workaround this unless using eval() code.

If I define a function within a loop with two variables (which should be different variables in my eyes, and their content is different in the time of defining this function), all functions I defined in the loop are using the exact same variable (and exact same content). I created a very simple example demonstrating this:

var inputParams = ['x', 'y'];
var funcs = [];
for(var i = 0; i < 2; i++) {
    var variableInLoop = inputParams[i];
    var funcInLoop = function(){return 'prefix '+variableInLoop;};
    funcs.push(funcInLoop);
}

After this code, funcs[0]() funcs[1]() will return the same result: 'prefix y'.

I create the same example here:

http://jsfiddle.net/LFr4U/3/

Whats the reason for this behaviour?

Thanks and regards
Paul.

[toc] | [next] | [standalone]


#18934

FromCezary Tomczyk <cezary.tomczyk@gmail.com>
Date2013-03-18 17:44 +0100
Message-ID<ki7g9a$c9a$1@speranza.aioe.org>
In reply to#18928
W dniu 2013-03-18 13:29, pwellner@gmail.com pisze:
[...]

> I create the same example here:
>
> http://jsfiddle.net/LFr4U/3/

My updated version:
http://jsfiddle.net/LFr4U/6/

-- 
Cezary Tomczyk
http://www.ctomczyk.pl/

[toc] | [prev] | [next] | [standalone]


#18935

FromGregor Kofler <usenet@gregorkofler.com>
Date2013-03-18 18:04 +0100
Message-ID<ki7hba$fp2$1@dont-email.me>
In reply to#18928
Am 2013-03-18 13:29, schrieb pwellner@gmail.com:

> I have a mysterious problem in my JavaScript which is -- or seems to be -- in the nature of JavaScript itself, but I don't find the reason why and I don't have any idea of how to workaround this unless using eval() code.
>
> If I define a function within a loop with two variables (which should be different variables in my eyes, and their content is different in the time of defining this function), all functions I defined in the loop are using the exact same variable (and exact same content). I created a very simple example demonstrating this:
>
> var inputParams = ['x', 'y'];
> var funcs = [];
> for(var i = 0; i < 2; i++) {
>      var variableInLoop = inputParams[i];
>      var funcInLoop = function(){return 'prefix '+variableInLoop;};
>      funcs.push(funcInLoop);
> }
>
> After this code, funcs[0]() funcs[1]() will return the same result: 'prefix y'.

As expected. Once the loop finishes you have two function bodies with 
the same content:

return 'prefix ' + variableInLoop;

and variableInLoop holds the value 'y'. You want to look up the concept 
of closures

https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Closures

and keep in mind that JS is function scoped, not block scoped.

Gregor

[toc] | [prev] | [next] | [standalone]


#18944

FromJim T. <x@y.z>
Date2013-03-19 12:01 -0500
Message-ID<9n5hk8hkcncrs2ev9vrums58lkde57fj13@4ax.com>
In reply to#18928
On Mon, 18 Mar 2013 05:29:04 -0700 (PDT), pwellner@gmail.com wrote:

>I have a mysterious problem in my JavaScript which is -- or seems to be -- in the nature of JavaScript itself, but I don't find the reason why and I don't have any idea of how to workaround this unless using eval() code.
>
>If I define a function within a loop with two variables (which should be different variables in my eyes, and their content is different in the time of defining this function), all functions I defined in the loop are using the exact same variable (and exact same content). I created a very simple example demonstrating this:
>
>var inputParams = ['x', 'y'];
>var funcs = [];
>for(var i = 0; i < 2; i++) {
>    var variableInLoop = inputParams[i];
>    var funcInLoop = function(){return 'prefix '+variableInLoop;};

The problem is that variableInLoop retains its last value in each
created function

Try instead: 
 var funcInLoop =
     ( function(x)  {
        return function(){ return 'prefix'+x ;};
     } ) ( variableInLoop );

Using a self invoking function this way in essence creates a new copy
of variableInLoop for each function.

>    funcs.push(funcInLoop);
>}
>
>After this code, funcs[0]() funcs[1]() will return the same result: 'prefix y'.
>
>I create the same example here:
>
>http://jsfiddle.net/LFr4U/3/
>
>Whats the reason for this behaviour?
>
>Thanks and regards
>Paul.

[toc] | [prev] | [next] | [standalone]


#18945

FromJim T. <x@y.z>
Date2013-03-19 12:25 -0500
Message-ID<9i7hk852dn14h6n3bj8sdhpnpc04vb1sr3@4ax.com>
In reply to#18944
On Tue, 19 Mar 2013 12:01:26 -0500, Jim T. <x@y.z> wrote:

>On Mon, 18 Mar 2013 05:29:04 -0700 (PDT), pwellner@gmail.com wrote:
>
>>I have a mysterious problem in my JavaScript which is -- or seems to be -- in the nature of JavaScript itself, but I don't find the reason why and I don't have any idea of how to workaround this unless using eval() code.
>>
>>If I define a function within a loop with two variables (which should be different variables in my eyes, and their content is different in the time of defining this function), all functions I defined in the loop are using the exact same variable (and exact same content). I created a very simple example demonstrating this:
>>
>>var inputParams = ['x', 'y'];
>>var funcs = [];
>>for(var i = 0; i < 2; i++) {
>>    var variableInLoop = inputParams[i];
>>    var funcInLoop = function(){return 'prefix '+variableInLoop;};
>
>The problem is that variableInLoop retains its last value in each
>created function
>
>Try instead: 
> var funcInLoop =
>     ( function(x)  {
>        return function(){ return 'prefix'+x ;};
>     } ) ( variableInLoop );
>
>Using a self invoking function this way in essence creates a new copy
>of variableInLoop for each function.

What I wrote is worded badly. It's better to say that in your version
each function references the same variable 'variableInLoop' which of
course has the same value in each function. In my version the self
invoking function creates a closure that locally stores a copy of the
current value of 'variableInLoop'.

>>    funcs.push(funcInLoop);
>>}
>>
>>After this code, funcs[0]() funcs[1]() will return the same result: 'prefix y'.
>>
>>I create the same example here:
>>
>>http://jsfiddle.net/LFr4U/3/
>>
>>Whats the reason for this behaviour?
>>
>>Thanks and regards
>>Paul.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web