Understanding JavaScript Hoisting: Why console.log(test) Returns Undefined
JavaScript executes code by first compiling function and var declarations within a scope, then running statements top‑to‑bottom, which explains why accessing a var‑declared variable before its assignment yields undefined while referencing an undeclared variable throws an error, as illustrated through detailed examples.
JavaScript may appear to run code line by line from top to bottom, but in reality it first compiles declarations within the current scope and then executes statements sequentially.
During the compilation phase, function and var declarations are hoisted. The variable name is created, but its assignment is not performed until the execution phase reaches the assignment statement.
Example 1 demonstrates this behavior:
console.log(test); // undefined because only the declaration is hoisted
var test = "你好"; // assignment happens here
console.log(test); // "你好"
console.log(test2); // ReferenceError: test2 is not definedWhen the first console.log(test) runs, the variable test has been declared (so no error) but not yet assigned, resulting in undefined. The identifier test2 was never declared, so accessing it throws a ReferenceError.
The compilation steps can be visualized as:
// Hoist var declaration
var test;
// Execution phase
console.log(test); // undefined
test = "你好";
console.log(test); // "你好"
console.log(test2); // ReferenceErrorFunction declarations follow a similar but slightly different rule: the entire function body is hoisted and assigned to the function name.
test(); // prints "你好"
function test() {
console.log("你好");
}Internally this is equivalent to:
// Hoist function as a variable holding the function object
var test = function () {
console.log("你好");
};
// Execution phase
test();A more complex example shows how inner function declarations create local bindings that shadow outer variables:
var a = 1;
function test() {
a = 2; // refers to the outer variable unless a local one is created
function a() {} // creates a local function named a, hoisted before the assignment
}
test();
console.log(a); // still 1 because the inner <code>a</code> is a separate local bindingDuring compilation, the inner function a is hoisted, turning a into a local variable inside test. Consequently, the assignment a = 2 modifies the local a, leaving the outer a unchanged.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java High-Performance Architecture
Sharing Java development articles and resources, including SSM architecture and the Spring ecosystem (Spring Boot, Spring Cloud, MyBatis, Dubbo, Docker), Zookeeper, Redis, architecture design, microservices, message queues, Git, etc.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
