When you define a variable with var
, the declaration of the variable is "hoisted" to the top of the scope and thus the variable is defined for the entire scope. The initialization of the variable (assigning it's initial value) remains at the same location in the code.
So, in your second example, when you do alert(box)
, the variable box
has already been declared because of the hoisted var
statement. Your second example:
alert(box);
var box = "Thinking outside the box";
is basically equivalent to this (the declaration of the box
variable is hoisted to the top of the scope):
var box;
alert(box);
box = "Thinking outside the box";
This makes the box
variable declared (though not initialized) before your alert(box)
statement and thus you get a result that is consistent with the variable being declared, but having no value yet (the alert()
reports undefined
which is what happens when the variable exists, but is not yet initialized).
Your first example does not use var
and thus there is no hoisting so at the point where you do alert(box)
, there is no variable at all named box
and thus you get the uncaught reference error
.
There are many, many posts here on SO that describe the details of hoisting. You can see a long list of them here: https://stackoverflow.com/search?q=javascript+variable+hoisting where you will find further explanation of variable hoisting.
Note: function declarations are also hoisted so some of the posts you find will be about function declarations rather than variable declarations, though the concept is pretty much the same.