I came across this JavaScript code snippet and noticed it behaves a bit unexpectedly:
```javascript
var x = 10;
function test() {
console.log(x);
var x = 20;
}
test();
```
The output is `undefined`, not `10`, and I'm trying to grasp why that happens. From what I understand, `var` declarations are hoisted and initialized as `undefined` within the function scope, but I want to dive deeper into how the JavaScript engine resolves this. Specifically:
* When does the inner `var x` shadow the outer `x`?
* How would this change if I used `let` or `const` instead?
I'd love to get a better mental picture of execution context and hoisting mechanisms in scenarios like this.
4 Answers
From a parsing stage perspective, hoisting occurs when all variables are lifted to the top of their scope in the order they appear. This behavior ensures that `var` declarations are available throughout the function, making it a bit more forgiving, but many modern JavaScript best practices encourage using `let` and `const` for better scope management.
According to the MDN documentation on hoisting, `var` declarations are processed before executing any code, essentially moving the declaration to the top within its scope. This means the inner `var x` is hoisted, but not its initialization (`= 20`). So, you’re able to log `x` before its declaration, resulting in `undefined`.
With `let` or `const`, referencing them too early will lead to an error since they can't be accessed until the execution reaches their actual lines.
The JavaScript engine processes your function in two stages. First, during the creation phase, it looks for all variable declarations and sets them to undefined in the local scope. So before any code runs, you technically have your own local `x` as undefined. In the second stage, it executes line by line: when `console.log(x)` runs, the local `x` is still undefined, and then it assigns `20` to `x` afterward. If you used `let` or `const`, you'd hit a ReferenceError because they exist in a 'temporal dead zone' until their declaration.
The inner `var x` shadows the outer `x` immediately when the function starts executing. This is because hoisting occurs beforehand, where the engine identifies all variable declarations so it knows which ones are local. For `var`, that means the variable is set to `undefined` during the hoisting phase.
When using `let` or `const`, things are a bit different. While they are still hoisted, they aren't initialized, leaving them uninitialized. Accessing them before the declaration will throw a ReferenceError instead of returning `undefined`.

Related Questions
How To: Running Codex CLI on Windows with Azure OpenAI
Set Wordpress Featured Image Using Javascript
How To Fix PHP Random Being The Same
Why no WebP Support with Wordpress
Replace Wordpress Cron With Linux Cron
Customize Yoast Canonical URL Programmatically