Prior to ES6, JavaScript would "hoist" variable declarations to the function level. In other words, a variable declared anywhere in the body of the function acts like it had been declared at the top of the function.
Consider:
When the x function is executed, the browser displays an error such as:
Uncaught ReferenceError: z is not defined
at x (<anonymous>:1:27)
Then consider:
As expected, there is no error, and because we did not define a value for z, the displayed value is
undefined. Note that the value
undefined, is not the same as
undeclared -- the variable exists (is declared), but has no value (
undefined).
Now consider:
You would think that the log statement would fail, but the value displayed is
undefined because the variable declaration is "hoisted" to the top of the function, just like the previous example.
Note that:
Does
not display 1, because even though the variable declaration is hoisted to the top of the function, the
initialization still occurs after the log statement is executed.
As of ES6, JavaScript has block scoping rather than function scoping.