12
function f1() {
   for (i = 0; i <= 5; i++)
      console.log(i);
}
function foo() {
   for (i = 0; i < 5; i++)
      f1();
}
foo();

Hi, I'm trying to understand why the result of executing foo is:

0
1
2
3
4
5

And not:

0
1
2
3
4
5
0
1
2
3
4
5
0
1
2
3
4
5
0
1
2
3
4
5
0
1
2
3
4
5

It's a slide I am reading about JS and its talking about when you don't use var then it is defined on the global object and provides this example without any further details why we get the result.

I thought it will simply loop and run the f1 function each time until its less than 5.

Please help me understand.

Thanks

5
  • 16
    i is global and shared between your functions. Use var to make both instances local. Commented May 28, 2014 at 11:31
  • Thanks for all your responses. I already tested with var and got the result I was expecting. I wanted to understand why it was doing that. Commented May 28, 2014 at 11:39
  • Correct me if I am wrong. So basically, because the script encounters the i in f1, it runs this and doesn't bother running the i in foo??? Commented May 28, 2014 at 11:41
  • @Kam: I've added a short description of what's happening to my answer. Commented May 28, 2014 at 11:46
  • 1
    The fact is that, as written, i is a shared global variable, so foo starts, sets is to 0 then calls f1 which loop on it up to 5, when control returns to foo it founds that i is 5 and so it ends the loop. Commented May 28, 2014 at 11:46

2 Answers 2

17

The problem is in your iterators (i):

for (i = 0; i <= 5; i++)

i is global, and both your for loops test against it, making them only run once, and aborting when i == 5.

So, what happens is this:

When you call foo(), foo tells the js interpreter to create a variable in the global scope called i, and set it to 0. Then foo calls f1.
There, the for loop sets i, which already exists, to 0, and runs it's loop like it should, incrementing i up to 5.
Then, it's time for the second iteration of the loop in foo, so it checks if i < 5, but it's not (i==6 (5 from f1, +1 from foo)), so it will not call f1 again.

To fix this, either declare them in the function's local scope using var:

function f1() {
    for (var i = 0; i <= 5; i++)
        console.log(i);
}
function foo() {
    for (var i = 0; i < 5; i++)
        f1();
}
foo();

Or, use different variables:

function f1() {
    for (i = 0; i <= 5; i++)
        console.log(i);
}
function foo() {
    for (j = 0; j < 5; j++)
        f1();
}
foo();

However, this second option is a bad idea, since it will both place i and j in the global scope, which is asking for conflicts. I'd suggest using the var option.

Sign up to request clarification or add additional context in comments.

4 Comments

@Downvoter: I edited in a bit of information explaining why option 2 isn't a good idea. I'd appreciate if the downvote could be removed.
Good answer but I can't approve the second solution. Using global variables like this will inevitably cause problems and become a pain to debug.
@sebcap26: And that's exactly why I said that the second option is a bad idea, right below that option.
Actually, after f1 has executed, it should be i == 6
9

If you write your loop like

for (i = 0; i < 5; i++)

here i refers to a global variable, because you have not declared it with the var keyword, and since you use i in both functions, they end up actually using the same variable.

You should then replace both loops with

function f1() {
   for (var i = 0; i <= 5; i++)
      console.log(i);
}
function foo() {
   for (var i = 0; i < 5; i++)
      f1();
}
foo();

As your code is originally written, i is a shared global variable, so foo starts, sets is to 0 then calls f1 which loop on it up to 6, when control returns to foo it founds that i is 6, so i < 5 is false and so it ends the loop.

1 Comment

this is a precise and direct answer to the question

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.