serg
serg

Reputation: 111265

How to explain this issue with variable scope?

Why does the second function output an empty array?

var global = ["abc"];

function test1() {
    var g = global || [];
    console.log(g);             //outputs: ["abc"]
}

function test2() {
    var global = global || [];
    console.log(global);        //outputs: []
}

Upvotes: 2

Views: 90

Answers (3)

user113716
user113716

Reputation: 322462

While it seems like it should work because assignment works right to left, you need to consider that variable declarations are hoisted.

To the interpreter, your code actually looks like this:

function test2() {
    var global; // global is undefined

    global = global || []; // because undefined is falsey, the [] is assigned

    console.log(global); // displays the []
}

Upvotes: 5

JaredPar
JaredPar

Reputation: 754575

The reason it outputs an empty name is because once you have conflicting names. There is both a local and global named global. Inside the function which defines global as a local all occurrences will refer to the local. It will never see the global value.

Hence the line var global = global || [] interprets global as a local. It is currently undefined hence it chooses [].

One way to make this work is to use the qualified name for the global instance

function test2() {
  var global = window.global || [];
  console.log(global); // outputs ["abc"]
}

Upvotes: 0

jfriend00
jfriend00

Reputation: 707218

var global redefines the symbol global to be a local variable within the scope of that function, thus making the other global invisible. If you want to do what that second function does, use a different name:

var global = ["abc"];

function test2() {
    var local = global || [];
    console.log(local);        //outputs: ["abc"]
}

or, if the original definition of global is truly a global variable, you can use the window object to reference it, when it's regular symbol is hidden by a local variable (though I would not suggest doing this because it will likely confuse people trying to understand your code):

var global = ["abc"];

function test2() {
    var global = window.global || [];
    console.log(global);        //outputs: ["abc"]
}

Upvotes: 1

Related Questions