2

Take this for example.

if (b) b = 1;

Reference Error. b is not defined. Makes sense but if I do this...

if (b) var b = 1;

I get undefined in console. and now when I look up what b is it shows as undefined.

If I try to do the same if statement again, it doesn't pass because b is neither true or false, it is undefined, but I guess my question is why does it show up as undefined? Does Javascript go through the if statement regardless if the if statement passes or fails? Thanks.

aug
  • 11,138
  • 9
  • 72
  • 93
  • 5
    `var` gets hoisted so `b` gets initialised as `undefined` at the beginning of the scope. Think of it like `var b; if (b) b = 1;`. – Paul S. Jan 23 '13 at 22:12
  • What Paul said, vars gets hoisted, and the obvious thing to do would be to declare your variables **before** you check if they are thruthy/falsy. – adeneo Jan 23 '13 at 22:13
  • 1
    possible duplicate of [Puzzled by this JavaScript code snippet](http://stackoverflow.com/questions/11397151/puzzled-by-this-javascript-code-snippet) (if you understand this question/answer, then you'll understand why it works as such) –  Jan 23 '13 at 22:15
  • 1
    http://stackoverflow.com/questions/13427311/local-variable-impact-global-variable-javascript-variable-scoping - another example of `var` in a conditional. –  Jan 23 '13 at 22:16
  • One clue: `b = undefined; if (b) ` will find b to be false because a bunch of values are false in javascript, including `null` and `undefined` and `0` and the empty string and others. – Lee Meador Jan 23 '13 at 22:21
  • @PaulS. if you put your comment as an answer, I'll accept it. I guess I was looking for the term variable hoisting. – aug Jan 23 '13 at 22:25
  • And thank you @pst I wish I saw those questions but couldn't find them! Also just wondering if variable hoisting is language-agnostic or is it something special in only Javascript? – aug Jan 23 '13 at 22:25
  • 1
    @aug This is very *language-specific* just as with the general Scoping rules. (JavaScript scope is somewhat similar to Python, but in Python one must declare globals, not locals; JavaScript scope is somewhat similar to Ruby, but Ruby requires a variable to appear as an lvalue before use and does not chain to a "global" scope; JavaScript scope is not very similar to C/Java in which each block introduces a new scope and variables must be declared ahead, etc ..) –  Jan 23 '13 at 22:28
  • ahh thank you :) @pst if you want to post an answer I can accept that too. – aug Jan 23 '13 at 22:29

2 Answers2

3

All vars gets hoisted to the beginning of the scope they are in, initialising their values to undefined. The value is then set when execution reaches the line the var was in originally.

In your second example, b gets initialised as undefined before the if is encountered, due to the var. Think of it as the same as writing the following

var b;
if (b) b = 1;

After this code is executed, b will still be undefined because it will never run into the if block as the initial value is falsy.

As mentioned by pst, this is a language specific feature of JavaScript, so don't expect the same behaviour when writing code in other languages.

Community
  • 1
  • 1
Paul S.
  • 64,864
  • 9
  • 122
  • 138
  • Do you have any official resource calling this behaviour "hoisting"? Like anywhere in the ECMAScript-Spec? – dave Jan 23 '13 at 22:50
  • @dave I was able to look it up and yes there is a term for hoisting. Crazy right? https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/var#var_hoisting – aug Jan 23 '13 at 22:56
0

JS is not going thru the if statement, but rather it's reading the if part of the statement, and since b is not defined anywhere but within the if statement, you get undefined.

dmayo
  • 640
  • 6
  • 16
  • 1
    This doesn't address the behavior of `var`. –  Jan 23 '13 at 22:14
  • I agree that it doesn't explain how putting `var` in front of a variable changes how global-ized (hoisted?), but I think that the OP was asking if JS goes thru the `if` statement, which I don't think it does if the `if` is false, no? – dmayo Jan 23 '13 at 22:20