'Hoisted' JavaScript Variables
I do not fully understand why the following displays "hoisted" towards the end.
var x = 'set';
var y = function ()
{
// WHAT YOU DON'T SEE -> var x;
// is effectively "hoisted" to this line!
if (!x)
{
// You might expect the variable to be populated at this point...it is not
// though, so this block executes
var x = 'hoisted';
}
alert(x);
}
//... and this call causes an alert to display "hoisted"
y();
Any pointers would be appreciated.
Solution 1:
Quoting MDN Docs on var
hoisting,
Because variable declarations (and declarations in general) are processed before any code is executed, declaring a variable anywhere in the code is equivalent to declaring it at the top. This also means that a variable can appear to be used before it's declared. This behavior is called "hoisting", as it appears that the variable declaration is moved to the top of the function or global code.
So, in your case, JavaScript knows that a local variable (not the one declared outside) x
is defined somewhere in the function, but it does not know the actual value of it until the execution reaches an assignment statement which assigns to x
. (Declarations are processed during the compile time and assigments are done in the execution time) Till the assignment is done, the default value undefined
will be used. Since undefined
is falsy, the condition
if (!x) {
is satisfied and the assignment statement is executed. That is why you are getting hoisted
in the alert box.
Let's say you have not declared x
inside the function,
var x;
var y = function () {
if (!x) {
x = 'hoisted';
}
alert(x);
}
y();
alert(x);
Here, since x
is not declared anywhere within the function, at runtime, JavaScript will look for x
in the higher scopes. In this case, it finds it right outside the function. So, that x
will be used. Since you assigned hoisted
to x
, the inner alert
will also say hoisted
and after leaving the function, alert(x)
will also alert hoisted
.
Solution 2:
Variable declarations hoist to the top of the scope. So your code is equivalent to this:
var x = 'set';
var y = function () {
var x;
if (!x) {
x = 'hoisted';
}
alert(x);
}
y();
When y
is executed, var x
shadows outer scope x
so inside of the y
function x
is undefined
after the first line of declaration.
Solution 3:
this answer explain in very detail the different scopes of the variables. In your particular case you can use the reference to:
this.x;
To access to the global x variable outside the function. Because inside of the function you are trying to access to an undefined variable, using the this
keyword you make a reference to variables outside of the function.
And the part of
if(!x)
It's true because you are testing: is false
and x
in that point is undefined
because does not exist in the function scope, and undefined
is consider one of the false values in JS, for more info please take a look here.