This is an analysis of what's happening with a debugger in Node.js. It doesn't explain why this is happening.
There are 3 scopes involved: local scope, global scope and block scope.
I did the same analysis in a Chrome browser. The behavior was similar with the only difference that there is no local scope and instead of the local scope the global scope was used.
The code
{
foo = 1;
foo = 2;
console.log(foo);
}
console.log(foo);
creates a variable in global scope and sets two different values for that variable. In this code
{
function foo() { }
foo = 1;
foo = 2;
console.log(foo);
}
console.log(foo);
the line function foo() { }
creates a variable foo
in block scope and a variable foo
in local scope (global scope in Chrome). Since there exists a variable in block scope foo = 1;
sets a value for the existing variable in block scope and doesn't create a variable in global scope. foo = 2;
sets a different value for the same variable. The first console.log(foo);
prints 2
from block scope and the second console.log(foo);
prints f foo() { }
from local scope (global scope in Chrome).
In this code
{
foo = 1;
function foo() { }
foo = 2;
console.log(foo);
}
console.log(foo);
the function declaration function foo() { }
is hoisted and creates a variable foo
in block scope with value f foo() {}
and a variable foo
in local scope (global scope in Chrome) with value undefined
. The line foo = 1;
sets both variables to 1
. The line foo = 2;
sets the variable in block scope to 2
. The first console.log(foo);
prints 2
from block scope and the second console.log(foo);
prints 1
from local scope (global scope in Chrome).
In this code
{
function foo() { }
foo = 1;
function foo() { }
foo = 2;
console.log(foo);
}
console.log(foo);
the function declaration function foo() { }
creates a variable foo
in block scope with value f foo() {}
and a variable foo
in local scope (global scope in Chrome) with value f foo() {}
. The line foo = 1;
sets both variables to 1
. The line foo = 2;
sets the variable in block scope to 2
. The first console.log(foo);
prints 2
from block scope and the second console.log(foo);
prints 1
from local scope (global scope in Chrome).