Shawn Erquhart
Shawn Erquhart

Reputation: 1858

Why is this console log affected by a subsequent if statement?

Consider the following code:

var a = 'a';

function b() {
    console.log(a);

    if (!a) {
        var a = 'b';
    }
}

b();

Running b() prints undefined to the console. However, if you remove the if statement, or even simply remove the var keyword from the expression within the if statement so that you're redefining the outer a variable, the string a will be printed to the console as expected.

Can anyone explain this? The only cause I can think of is that this is a race condition, and the if statement is running just a tad faster than the console.log.

Upvotes: 0

Views: 54

Answers (2)

thefourtheye
thefourtheye

Reputation: 239443

  1. When you use var statement in a function, it will be creating a new variable which is local to that function.

  2. All the variables declared in the function, will be moved to the top of the function, irrespective of the place where they are actually declared. This is called Hoisting.

  3. The hoisted variables will have the value undefined, by default, till they are explicitly assigned a value.

It prints undefined as it is, because of the 3rd point.

In your case, you declared a variable a within the if block. Since the variables are hoisted, the declaration is moved to the top of the function. It has the same name as the outer variable. When you access a in the function, it first looks in the current scope if there is a variable by that name exists. It checks other scopes only if it is not found in local scope. So, the local a shadows the outer a. When you remove the var statement, there is no a in local scope, so the outer a is used. That is why it prints a.

Upvotes: 1

jfriend00
jfriend00

Reputation: 707158

This is not a race condition - it's a language feature and is working as the designers of the Javascript language intended.

Because of hoisted variable definitions (where all variable definitions within a function scope are hoisted to the top of the function), your code is equivalent to this:

var a = 'a';

function b() {
  var a;
  console.log(a);

  if (!a) {
    a = 'b';
  }
}

b();

So, the locally declared a hides the globally declared a and initially has a value of undefined until your if statement gives it a value.

You can find lots of discussion about this characteristic of the Javascript language by searching for "Javascript hoisting".

Upvotes: 1

Related Questions