11

Can anyone explain why the following code works when run as part of function, but it produce strange result when run by itself in the Chrome Console window?

var foo = function() { 
    var x = 1;
    while (x<3) { 
        console.log(x);
        x = x+1;
    }
}

foo(); // This prints 1,2 as expected

But when I run just while part directly in Chrome Console I get 1,2,3 which makes no sense (see image for the output):

    var y = 1;
    while (y<3) { 
        console.log(y);
        y = y+1;
    }

    // This prints 1,2,3 in the console

enter image description here

Note that there somewhat similar question about console.log resulting in undefined (Chrome/Firefox console.log always appends a line saying undefined), but there is no function call in my sample and while does not ever return any value.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
fenderog
  • 314
  • 1
  • 3
  • 9
  • 5
    Do you have a jsFiddle proving your statement? – Lucero May 30 '13 at 01:37
  • 1
    If the second one returns that, you should trade in your browser for a newer version ? – adeneo May 30 '13 at 01:38
  • 2
    @fenderog both log the same for me, as expected - 1,2 – momo May 30 '13 at 01:38
  • Please run the code yourself next time – Stas Jaro May 30 '13 at 01:38
  • 1
    http://jsfiddle.net/uXFat/ – Stas Jaro May 30 '13 at 01:39
  • 1
    I'm running them in the chrome console – fenderog May 30 '13 at 01:42
  • Does @stas's fiddle repro the error for you? I get `1,2` like any sane person would expect.. – Mike Christensen May 30 '13 at 01:45
  • @fenderog: add a `;` at the end of the statement – Lucero May 30 '13 at 01:46
  • 5
    Friends, before you go downvoting this, it's a much more reasonable question than you may think. Try pasting that second piece of code into the Chrome console and you will see why it might be confusing. – Michael Geary May 30 '13 at 01:47
  • Exactly.. Chrome result can be rather misleading. – user1600124 May 30 '13 at 01:50
  • 1
    @MichaelGeary in our defense, this does fall under the vague category, There is a lot missing from the question. – Isaac May 30 '13 at 01:52
  • 1
    @MichaelGeary, I didn't downvote, but the question is badly asked because the OP writes "in global space" and not "in the Chrome console" - these two are very different things. For instance, when hitting a breakpoint, the console will be scoped to that code piece. It's not global by any means. – Lucero May 30 '13 at 01:52
  • 2
    @Isaac and Lucero - you are indeed right: the question as originally worded was definitely confusing. (And sorry for the harsh wording of my comment originally - I toned it down!) Mike Christensen made an excellent edit to the question, adding a screenshot showing the confusing output from the Chrome devtools. Much better with that screenshot! – Michael Geary May 30 '13 at 02:00
  • I've edited question a bit more as I was puzzled by the same behavior. Voting to re-open as I think it is quite clear now and does not speak about "global scope" anymore. – Alexei Levenkov Jan 29 '18 at 03:27
  • Does this answer your question? [Javascript while loop return value](https://stackoverflow.com/questions/35454291/javascript-while-loop-return-value) – Ivar Jun 09 '22 at 12:02

2 Answers2

14

You are being misled by Chrome's JavaScript console.

In addition to the output of console.log() calls, the console also displays the value of the last expression executed in the code you run there.

In your first example, the last expression is the foo(); call at the end. foo() doesn't return any value, so the result is undefined and that's what's printed after the 1 and 2 that your console.log(y) calls print.

In the second example, console.log() is still being called only twice, again printing 1 and 2. The 3 printed after that is not from a console.log() call, it's the value of the last expression executed, the final y = y + 1; that brings y up to 3 and causes the while loop to terminate.

Here's another example. Paste this code into the console:

var y = 1, message = '';
while( y < 3 ) { 
    console.log( y );
    y = y + 1;
    message = 'y is ' + y;
}

Now it prints:

1
2
"y is 3"

The 1 and 2 are again from the console.log(y) calls as before. Like the other examples, after the code finishes running it prints the last expression executed—but now that expression is:

message = 'y is ' + y;

where y is again 3 at the end.

Or a much simpler example. Enter this in the console:

console.log( 'Hi!' );

It prints:

Hi!
undefined

The Hi! is your console.log() executing, and the undefined is the return value of the console.log() call.

Another clue here is the little symbol to the left of the last value printed to the console in each of the examples. It looks like that symbol means that the dev tools are printing the value automatically instead of from a console.log() call.

Michael Geary
  • 28,450
  • 9
  • 65
  • 75
  • ah thank you. What is the explanation to that "3" print ? – fenderog May 30 '13 at 01:48
  • Perhaps the chrome devs think that outputing the terminating condition is helpful to fellow devs.. – user1600124 May 30 '13 at 01:48
  • Ah you're absolutely right! I'd remove my downvote if it would let me.. – Mike Christensen May 30 '13 at 01:52
  • @fenderog It's useful for evaluating expressions: I can type in `2 + 2` and get back `4` immediately, instead of doing `console.log(2+2)`. Also, what if I did `x = 4` and then ran the line "`x`" by itself? Would you *not* want it output the value of the expression `x`? – apsillers May 30 '13 at 01:53
  • @apsillers, outputting the expression result is useful, but in JS the `while` loop is not an expression, which makes the question as to why it does output something in that case (and, by the way, this changes to `undefined` if you add a semicolon) a pretty valid one. ;) – Lucero May 30 '13 at 01:55
  • @MikeChristensen - I edited the question to add some clarification; it's possible that this may let you undo your downvote. It's funny, my first reaction was as skeptical as everyone else's. Then I tried pasting the code into the Chrome console and was quite surprised by the result! – Michael Geary May 30 '13 at 01:56
  • @MichaelGeary, run this: `var foo = function() { var x = 1; while (x<3) { console.log(x); x = x+1; } return x; }; foo();` – Lucero May 30 '13 at 01:58
  • thank you all! I'll be more clear next time :) – fenderog May 30 '13 at 02:01
  • @Lucero - yes, that also outputs `1`/`2`/`3`. Similar situation to the original question, although perhaps a bit more clear why it prints `3` - it's the return value from `foo();`. – Michael Geary May 30 '13 at 02:02
1

It isn't just restricted to the console, as shown via:

<script>
console.log(eval("var y = 1;while (y<3) { console.log(y);y = y+1;}"))
</script>

That is a rough way to go about replicating the output, but it may be noted that eval will preform in the same way

Isaac
  • 11,409
  • 5
  • 33
  • 45