JavaScript Interview Questions for Beginners , Code Examples on Hoisting— Part 2
In Part 2 of our JavaScript Interview Questions series, we’ll unravel the enigma of hoisting. Understanding hoisting is crucial for acing JavaScript interviews and writing efficient code. I
Lets explore the concept of hoisting, its intricacies, and provide practical examples to help you grasp this essential JavaScript feature.
function test() {
console.log(a); // 1. This will log 'undefined'.
console.log(foo()); // 2. This will log '2'.
var a = 1;
function foo() {
return 2;
}
}
test();
Here’s the explanation of each step:
- Function Declaration (Hoisting): In JavaScript, function declarations are hoisted to the top of their containing scope. So,
test
is available throughout the entiretest()
function. - Variable and Function Declarations (Hoisting): Inside the
test
function, there are two declarations Variablea
is declared usingvar
. Functionfoo
is declared using a function declaration. Both variable and function declarations are hoisted to the top of thetest
function's scope. - Variable Initialization:
var a = 1;
initializes the variablea
with the value1
. This assignment occurs at the point where thevar
declaration is encountered during runtime. - Function Definition: The
foo
function is defined here. It doesn't execute immediately; it only defines a function that can be invoked later. - Function Return Value:
foo()
is called. This function returns2
. - Function Invocation (Execution): The
test
function is invoked withtest()
, which starts the execution of the function.
Now, let’s explain the output based on the steps:
console.log(a);
At this point,a
has been hoisted to the top of thetest
function's scope, but it hasn't been assigned a value yet. Therefore,console.log(a);
logsundefined
to the console.console.log(foo());
Thefoo
function is defined before this line, so it can be called. It returns2
, which is then logged to the console. This happens even though the function declaration forfoo
is placed after this line in the code.
The output of the code is:
undefined
2
This is due to the behaviour of variable and function hoisting in JavaScript, where declarations are moved to the top of their containing scope during the compilation phase, but variable assignments and function executions happen in the order they appear in the code during runtime.
var x = 5;
(function() {
console.log(x);
var x = 10;
console.log(x);
})();
console.log(x);
Explanation:
var x = 5;
: Here, a global variablex
is declared and initialized with the value5
. This variable is accessible throughout the global scope.- IIFE, an anonymous function that is immediately executed. Inside it, there’s a local variable
x
declared withvar
. The key thing to understand is that variable declarations withvar
are hoisted, meaning they are moved to the top of their containing scope during compilation. However, they are initialized withundefined
until they are assigned a value. - Inside the IIFE:
console.log(x);
: This firstconsole.log
statement prints the value ofx
. However, since there's a localx
variable declared inside the function, JavaScript interprets it as a local variable. As a result, the localx
is hoisted and initialized withundefined
, soundefined
is logged. var x = 10;
: Here, the localx
variable is assigned the value10
.- After the IIFE:
console.log(x);
: Finally, outside the IIFE, we log the global variablex
, which is still set to5
. It hasn't been affected by the local variablex
inside the IIFE.
Output Explanation:
- The first
console.log(x);
inside the IIFE logsundefined
because of hoisting, as it references the localx
before it is assigned a value. - The second
console.log(x);
inside the IIFE logs10
because it references the localx
after it has been assigned the value10
. - The last
console.log(x);
outside the IIFE logs5
because it references the global variablex
, which was never modified within the IIFE.
This behaviour highlights the importance of understanding hoisting and variable scope when working with JavaScript.
function example() {
console.log(name); // undefined
console.log(age); // ReferenceError: age is not defined
console.log(city); // ReferenceError: city is not defined
var name = "John";
let age = 30;
const city = "New York";
function greet() {
console.log(`Hello, ${name}!`);
}
greet();
var greet = function() {
console.log(`Hi, ${name}!`);
};
greet();
}
example();
Explanation:
- Inside the
example
function, we have variable declarations usingvar
,let
, andconst
. These variables are hoisted to the top of the function scope, but they have different behaviours due to their declarations. - There's a function declaration
function greet()
that is hoisted entirely, allowing it to be called before its declaration. - Later in the code, a function expression
var greet = function()
is assigned to thegreet
variable. This changes the behavior of thegreet
function.
Output Explanation:
console.log(name);
andconsole.log(age);
both printundefined
becausevar
andlet
variables are hoisted and initialized withundefined
. However,let
variables likeage
remain in the Temporal Dead Zone (TDZ) until their declaration, so accessing them results in a ReferenceError.console.log(city);
also results in a ReferenceError becauseconst
variables likecity
remain in the TDZ as well.greet();
initially calls the function declaration, which logs "Hello, John!" because the function declaration is fully hoisted.- The later assignment of a function expression to the
greet
variable changes its behaviour, and the subsequentgreet();
call logs "Hi, John!" because it now refers to the function expression.
This code snippet demonstrates the complexities of variable hoisting and function declarations vs. expressions in JavaScript, making it suitable for discussing hoisting in more detail during interviews.
Summary:
JavaScript hoisting is a process that takes place during the creation phase of an execution context. It involves moving variable and function declarations to the top of the script or function scope. Key points to understand about hoisting include:
- JavaScript hoists variables declared with the
let
keyword but doesn't initialize them immediately, unlike variables declared withvar
. - Function expressions and arrow functions are not hoisted in JavaScript. They remain in their original position in the code and are not moved to the top of the scope.
In essence, hoisting is a fundamental concept in JavaScript that affects the visibility and behaviour of variables and functions in your code during execution.