The behavior you're observing is a core aspect of JavaScript's hoisting mechanism, which applies differently to var
declarations and function
declarations.
Here's a breakdown:
Hoisting of var
Variables
When JavaScript processes your code, var
declarations are "hoisted" to the top of their scope (global or function scope). However, only the declaration is hoisted, not the assignment. Crucially, var
variables are also initialized with undefined
during the hoisting phase.
Consider your code:
JavaScript interprets this as if it were:
That's why console.log(num)
on the first line outputs undefined
instead of throwing an error. The variable num
exists, but its assigned value of 10
hasn't been reached yet.
Hoisting of function
Declarations
In contrast, function
declarations are hoisted in their entirety – both the function's name and its body are moved to the top of their scope. This means the entire function is available for use before it appears in the code.
For your greet
function:
JavaScript effectively processes this as:
This allows greet()
to be invoked successfully on the first line, returning "Hello, World!".
Summary of Differences
var
variables: Declaration is hoisted, initialized toundefined
. Assignment stays in place.function
declarations: Entire function (declaration and definition) is hoisted, making it fully available.
How let
and const
Differ
let
and const
also experience hoisting, but they behave differently from var
:
- No Default Initialization: While their declarations are hoisted,
let
andconst
variables are not initialized toundefined
. - Temporal Dead Zone (TDZ): If you try to access a
let
orconst
variable before its actual declaration in the code, JavaScript will throw aReferenceError
. This period between the start of the scope and the actual declaration is called the Temporal Dead Zone.
Example with let
and const
:
This behavior of let
and const
helps catch potential bugs related to accessing uninitialized variables and makes JavaScript code more predictable, which is why let
and const
are generally preferred over var
in modern JavaScript.