0

Quick question, because one thing confused me today. Below is piece of JavaScript code:

var a = [1, 2, 3, 4];

function init() {

    console.log(a);

    if (false) {
        var a = [9, 8, 7];
    }
}

init();

This simple code logs "undefined" in JS console. I found that the reason for this is 5th line:

var a = [9, 8, 7];

Without word var inside that condition, it will log correct result [1, 2, 3, 4].

My question here is: why JavaScript interpreter takes into consideration piece of code which never will be executed?

Example to play with: http://jsfiddle.net/5DPCz/

2 Answers 2

4

You cannot declare variables in the middle of a function in JavaScript; all variables have function scope. Effectively, variable declarations are "hoisted" to the top of the function. Your function will only ever have access to the local variable a regardless of where in the function it is declared.

This is why JSLint (and most other linting tools) will advise you to move all variable declarations to the top of the function; that's where they're effectively written anyways.

Regardless of where in your function you place your var a, your code effectively executes this way:

var a = [1, 2, 3, 4];

function init() {
    var a;

    console.log(a);

    if (false) {
        a = [9, 8, 7];
    }
}

init();
Sign up to request clarification or add additional context in comments.

4 Comments

Even if definition of that variable is surrounded by condition which will never be satisfied?
@KrzysztofSowa Yes. The initialization won't run, but the variable is still being introduced in the function, and it will always have function scope.
@meagar, Freuh - thanks for your answers! It now makes more sense.
0

Your example is equivalent to

var a = [1, 2, 3, 4];

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

    if (false) {
        a = [9, 8, 7];
    }
}

init();

Now you can see why it prints undefined. The a that is local to the function has not been assigned a value at that point yet.

If you remove the var you turn it into

var a = [1, 2, 3, 4];

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

    if (false) {
        a = [9, 8, 7];
    }
}

init();

So a in the function now refers to a from the global scope.

2 Comments

I know, but my question is - why? :) If I would do: if(false){ alert(1); } it would never show alert, because that line of code wouldn't be executed. I know it might be silly question, but I'm trying to understand mechanism which takes into consideration code which shouldn't even be reached by interpreter.
As meagar mentioned, it has to do with hoisting. Before the function runs, the JS interpreter will analyze it and find all parts where a variable declaration happens. It will then move the declarations to the beginning of the function, but keep the assignments at their positions. That's why all var declarations in the function scope shadow the outer scope, even if they only seem to be declared later in the code, and even if that code is unreachable.

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.