Good morning! Here's our prompt for today.
Understanding Variable Scoping in JavaScript
Let's dig into a fascinating JavaScript example to unravel the mystery of variable scoping.
The Code Snippet
Here's the code we'll be examining:
1var numOfBeers = 5;
2
3function getMoreBeers() {
4 console.log('I have this many beers: ' + numOfBeers);
5 var numOfBeers = 25;
6 return numOfBeers;
7}
8
9console.log('I now have this many beers: ' + getMoreBeers());What Do You Expect?
Before running the code, what do you think will be printed to the console? Take a moment to think it over.
Execution Results
Go ahead and execute the code. What do you see?
Your job in the interview is to explain why it runs the way it does.
Try to solve this here or in Interactive Mode.
How do I practice this challenge?
xxxxxxxxxxvar assert = require('assert');var numOfBeers = 5;function getMoreBeers() { console.log('I have this many beers: ' + numOfBeers); var numOfBeers = 25; return numOfBeers;}console.log('I now have this many beers: ' + getMoreBeers());Here's how we would solve this problem...
How do I use this guide?
Analyzing Output in JavaScript: The Case of Mysterious Beers
The Code and Its Output
Let's look at the JavaScript code snippet and its output when executed:
1var numOfBeers = 5;
2
3function getMoreBeers() {
4 console.log('I have this many beers: ' + numOfBeers);
5
6 var numOfBeers = 25;
7 return numOfBeers;
8}
9
10console.log('I now have this many beers: ' + getMoreBeers());
11
12// Output
13// I have this many beers: undefined
14// I now have this many beers: 25Your Initial Guess vs Reality
Upon a first look, you might expect the output to show the number of beers as 5 and then 25. However, the output is quite different. Let's explore why.
xxxxxxxxxxvar numOfBeers = 5;function getMoreBeers() { console.log('I have this many beers: ' + numOfBeers); var numOfBeers = 25; return numOfBeers;}console.log('I now have this many beers: ' + getMoreBeers());// I have this many beers: undefined// I now have this many beers: 25Exploring Call Stack and Variable Hoisting: JS Execution
Console Log Order: The Call Stack in Action
The first thing to notice is the order in which the console log statements appear. The statement "I have this many beers" within the getMoreBeers function is printed before "I now have this many beers."
1console.log('I have this many beers: ' + numOfBeers);Why does this happen? It's all thanks to the call stack, a data structure that keeps track of function calls. The call stack operates based on a stack data structure, which follows a First-In-Last-Out (FILO) principle.
When this line of code runs:
1console.log('I now have this many beers: ' + getMoreBeers());It becomes the first frame on the call stack.
Function Calls and the Call Stack
However, as soon as getMoreBeers() is invoked, it gets pushed onto the top of the call stack, superseding the original console.log statement.
1function getMoreBeers() {
2 console.log('I have this many beers: ' + numOfBeers);
3 var numOfBeers = 25;
4 return numOfBeers;
5}Only after getMoreBeers() fully executes, including its log statement, does the original console.log statement get popped off the stack and executed.

Hoisting: The Underlying Phenomenon
Now, let's delve into hoisting, which explains the value undefined in the output. In JavaScript, variable declarations are "hoisted" to the top of their respective scopes but remain uninitialized. This is why the numOfBeers inside getMoreBeers() is undefined during the first console.log.
1console.log('I have this many beers: ' + numOfBeers); // Output: undefinedUnderstanding the mechanics of the call stack and variable hoisting is crucial for both debugging and technical interviews.
Are you sure you're getting this? Click the correct answer from the options.
What is a call stack?
Click the option that best answers the question.
- A data structure for telephone calls
- A stack that tracks method calls in a program
- An ordering mechanism
- A log of all the functions called
The Output Mystery
You've noticed that the output is intriguing. Despite having the variable numOfBeers defined before the function, the console log within the function prints it as undefined.
1// Output
2// I have this many beers: undefined
3// I now have this many beers: 25The Role of Scoping and Hoisting
This oddity has to do with two core JavaScript concepts: scoping and hoisting.
Local vs Global Scope: Even though a variable with the same name exists in the global scope, JavaScript gives priority to the local scope within a function.
JAVASCRIPT1var numOfBeers = 5; // Global ScopeHoisting in Action: In JavaScript, all variable declarations are "hoisted" to the top of their scope. This means that as soon as the function
getMoreBeers()begins execution, JavaScript hoists the variablenumOfBeersto the top of the function, but it remains uninitialized.JAVASCRIPT1function getMoreBeers() { 2 console.log('I have this many beers: ' + numOfBeers); // Local Scope, Hoisted but uninitialized 3 var numOfBeers = 25; // Local Scope, Initialized 4 return numOfBeers; 5}The Undefined Log: When the
console.logstatement withingetMoreBeers()runs, it finds the local, hoisted, but uninitializednumOfBeersand prints it asundefined.JAVASCRIPT1console.log('I have this many beers: ' + numOfBeers); // Output: undefined
Global Variable: A Common Misconception
Note that var numOfBeers = 5; is a globally defined variable. Intuitively, one might think that this global variable should be accessible within the getMoreBeers function.
1var numOfBeers = 5; // Globally Defined VariableHoisting: The Culprit
However, this expectation is thwarted by hoisting. Recall that hoisting moves variable declarations to the top of their current scope during the compilation phase.

var vs const and let
The hoisting behavior is specific to the var keyword, making it distinct from const and let. During the lexical analysis step by JavaScript engines, the var numOfBeers inside getMoreBeers is hoisted to the top of the function's scope, even before the function executes.
1function getMoreBeers() {
2 // Hoisted but uninitialized
3 var numOfBeers;
4 console.log('I have this many beers: ' + numOfBeers); // Output: undefined
5 numOfBeers = 25; // Initialization
6 return numOfBeers;
7}Breaking it Down: What Really Happens
So, when getMoreBeers runs, JavaScript's hoisting places a new var numOfBeers; at the top of the function, without initializing it. This local variable shadows the global one, and since it's uninitialized, the log statement shows undefined.
xxxxxxxxxxfunction getMoreBeers() { // var numOfBeers; console.log('I have this many beers: ' + numOfBeers); var numOfBeers = 25; return numOfBeers;}However, JavaScript only hoists declarations, not initializations. So the = 25 part is NOT hoisted alongside, thus numOfBeers is undefined when console.log('I have this many beers: ' + numOfBeers); is first run.

Complexity of Final Solution
O(1) constant time & space complexity, this is a knowledge question!
One Pager Cheat Sheet
- We can observe that the
getMoreBeers()function overwrites thenumOfBeersvariable, therefore when it is logged25will be printed out, which can be explained by scope. Executingthis code willprinttheoutput.- The order of the console log statements is determined by how the
call stackworks, with thegetMoreBeers()function pushing the original statement onto the stack and executing first. - A call stack is a
data structurethat allows a program to keep track of function calls using thestack(first in, last out) data structure. - The
variableis returned as "undefined" in the log despite being clearly defined above the function. - We should
let/constand keep track of variable declarations to avoid unexpected results due tohoisting. - The declarations of variables with the
varkeyword in JavaScript are hoisted, but not the initializations.
This is our final solution.
To visualize the solution and step through the below code, click Visualize the Solution on the right-side menu or the VISUALIZE button in Interactive Mode.
xxxxxxxxxxvar assert = require('assert');var numOfBeers = 5;function getMoreBeers() { console.log('I have this many beers: ' + numOfBeers); var numOfBeers = 25; return numOfBeers;}console.log('I now have this many beers: ' + getMoreBeers());Great job getting through this. Let's move on.
If you had any problems with this tutorial, check out the main forum thread here.

