48

In essence, I am trying to declare a variable in the condition-part of a while loop in javascript:

while (var b=a.pop()) {
  do_sth(b)
}

Yet, my browser (firefox) doesn't accept that. Instead I have to go like so:

var b
while (b=a.pop()) {
  do_sth(b)
}

which works. Is this behaviour expected?

Nakilon
  • 34,866
  • 14
  • 107
  • 142
René Nyffenegger
  • 39,402
  • 33
  • 158
  • 293
  • 1
    The 2 below explain variable declaration hoisting but don't explain why you can't declare a variable inside a `while` condition (but you can, for example, in a `for` condition). Did you ever find a good explanation for this? – Barney Mar 04 '14 at 11:03
  • 2
    Another JS quirk, thats why. – Ivan Kleshnin Dec 17 '14 at 10:13
  • if I were you, I'd consider (re)accept the answer by Ben Fletcher – YakovL Mar 09 '19 at 20:55

4 Answers4

45

Yes, it is.

If you want to, you can use a for loop, like this:

for (var b; b = a.pop(); ) {      //Note the final semicolon
    do_sth(b);
}
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 4
    `for` is syntactic sugar –  Jun 09 '19 at 10:51
  • 12
    @PauliSudarshanTerho On what planet is one of the most ubiquitous language constructs considered "syntactic sugar"? – maiorano84 Aug 15 '19 at 20:49
  • It is a `while` + a declaration + the last statement, made into one bit of sugar. But now I see the big distinction here is that `while` has an *expression* that can not include `var` but a `for` is three *statements* that can have a `var`. So - specifically I was wrong for this language. +1 to you –  Aug 15 '19 at 23:09
  • @PauliSudarshanTerho it's called syntax – neaumusic Nov 18 '19 at 05:45
  • ... sugar - Syntax sugar - Kind of (yes mush info in this sentence I know). A `for` statement is actually three statements. In that way the `for` is then syntactic sugar for a `while` where the declarationpart is made outside (and it is in Javascript anyway). And the increment/decrement is made inside the body of while usually as the last statement. –  Nov 19 '19 at 14:41
  • The Javascript language could be improved by a modification kind of in such way that the `var` is an expression instead of a sentence. It is possible to have expression as sentence in Javascript so a declaration as an expression or sentence should both be legal. If an expresion the assigned value should be a result of the expression. –  Nov 19 '19 at 14:45
  • Intellij/Webstorm might output a warning, thinking that the single `=` is accidental. Wrapping the assignment in parentheses makes it go away: `for (let b; (b = a.pop());) {` – Rapti Aug 05 '23 at 15:43
43

The question is a little dated, but I think the answers all miss an important distinction. That is, a while loop expects an expression that evaluates to a conditional, i.e., a boolean or value that can be converted to a boolean. See Mozilla docs for details.

A pure assignment (without instantiation) is coerced to a boolean via its default return value (the value of the right-hand-side).

A var (or let or const) is a statement that allows an optional assignment but has a return value of undefined.

You can easily test this in your console:

var foo = 42; // undefined
bar = 42      // 42

The return values alone don't answer the question, since undefined is falsey, but does show that even if JS let you put a var in a conditional it would simply always evaluate to false.

Others have mentioned for statements and that they allow declaration and instantiation of variables. This is true, but the documentation explains that for expects a statement or assigment.

Opinions may vary, but for me all this adds up to an understandable consistency not a quirk in behavior with regard to loops. A while loop is better thought of as a looping version of an if statement than akin to a for loop. If there is quirkiness in all of this, it's the for statement's wholesale divergence from the language's normal syntax.

ballenf
  • 894
  • 10
  • 19
  • 5
    I was looking for 'why?' javascript doesn't allow const,let,var inside while conditionals and this answered my question. I always found it confusing that the console reported undefined when i created a new variable, rather than the value of the variable. I still don't see the point of javascript returning undefined; they may as well return the value of the variable, but if it returns undefined, better browsers and compilers error when used in conditionals. – Sophie McCarrell Jul 29 '17 at 21:30
16

JavaScript does not have block scope. It has function scope. So to make sure that humans and JavaScript both read the code the same way, you should manually hoist your var declarations right up to the top of functions.

Here's what JSLint says about your code:

Problem at line 1 character 8: Expected an identifier and instead saw 'var'.

Use JSLint, at least while you're learning JavaScript. You'll learn a lot very quickly. It will hurt your feelings.

Nosredna
  • 83,000
  • 15
  • 95
  • 122
5

JavaScript doesn't have block scope. So all var declarations are at function scope. So declaring a variable in a while expression doesn't make sense in JavaScript.

Additionally, you should end your statements with a semicolon. It's not strictly necessary, but it's highly recommended.

Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135