DEV Community

Cover image for "Master JavaScript Hoisting: 10 Tricky Output Questions Every Developer Must Know!" Part 1
hithesh.kumar
hithesh.kumar

Posted on

"Master JavaScript Hoisting: 10 Tricky Output Questions Every Developer Must Know!" Part 1

JavaScript hoisting is one of the most important yet often misunderstood concepts for developers, especially when working with variable declarations and function scopes. Hoisting essentially allows you to use functions and variables in your code even before they are formally declared. While this might seem like magic, understanding how JavaScript interprets and rearranges code can help you avoid common pitfalls and write more predictable, efficient programs.

In this article, we’ll dive into hoisting through a series of output-based questions, ranging from beginner to advanced levels. Each question is followed by an explanation of the concept behind it, helping you solidify your understanding of how JavaScript hoists variables and functions during execution.

Let’s explore some key hoisting-related output questions and break down the behavior you need to be aware of when writing JavaScript.


1. Variable Hoisting with var

Question:

console.log(x);
var x = 10;
console.log(x);
Enter fullscreen mode Exit fullscreen mode

Output:

undefined
10
Enter fullscreen mode Exit fullscreen mode

Explanation:

In JavaScript, var declarations are hoisted to the top of their scope but are initialized with undefined. When console.log(x) is called before the initialization, x is hoisted but not yet assigned the value 10, so it outputs undefined. After the initialization, x holds the value 10.

Concept:

  • Hoisting: Variable declarations are moved to the top of the scope, but the initialization happens in place.

2. Hoisting with Function Declaration

Question:

console.log(foo());

function foo() {
    return "Hello!";
}
Enter fullscreen mode Exit fullscreen mode

Output:

Hello!
Enter fullscreen mode Exit fullscreen mode

Explanation:

Function declarations are hoisted in their entirety, including the function body. So, even though foo() is called before the function definition, it works as expected because the function is fully hoisted to the top.

Concept:

  • Function Hoisting: Entire function declarations (including the body) are hoisted to the top of the scope.

3. Hoisting with let and const

Question:

console.log(a);
let a = 5;
Enter fullscreen mode Exit fullscreen mode

Output:

ReferenceError: Cannot access 'a' before initialization
Enter fullscreen mode Exit fullscreen mode

Explanation:

Variables declared with let and const are hoisted but enter a "temporal dead zone" (TDZ) from the start of the block until they are initialized. This means that even though the declaration is hoisted, accessing a before its initialization will throw a ReferenceError.

Concept:

  • Temporal Dead Zone (TDZ): Variables declared with let and const are hoisted but cannot be accessed before initialization.

4. Hoisting with var inside a Function

Question:

function test() {
    console.log(a);
    var a = 10;
    console.log(a);
}

test();
Enter fullscreen mode Exit fullscreen mode

Output:

undefined
10
Enter fullscreen mode Exit fullscreen mode

Explanation:

Within the function test(), the var declaration of a is hoisted to the top of the function. So, the first console.log(a) outputs undefined because the variable is hoisted but not yet initialized. After initialization, the second console.log(a) prints 10.

Concept:

  • Function Scope Hoisting: Inside a function, variables declared with var are hoisted to the top of the function, initialized as undefined.

5. Hoisting with Multiple var Declarations

Question:

console.log(a);
var a = 10;
var a = 20;
console.log(a);
Enter fullscreen mode Exit fullscreen mode

Output:

undefined
20
Enter fullscreen mode Exit fullscreen mode

Explanation:

JavaScript allows multiple var declarations in the same scope, but only the first declaration is hoisted. The initial console.log(a) logs undefined due to hoisting, and the last console.log(a) logs 20 because the second assignment overwrites the first one.

Concept:

  • Multiple Declarations with var: Multiple var declarations in the same scope are allowed but only the final assignment takes effect.

6. Hoisting with Function Expressions

Question:

console.log(foo);

var foo = function() {
    return "Hello!";
};

console.log(foo());
Enter fullscreen mode Exit fullscreen mode

Output:

undefined
Hello!
Enter fullscreen mode Exit fullscreen mode

Explanation:

In this case, foo is declared using a function expression. The variable foo is hoisted to the top and initialized with undefined. Therefore, the first console.log(foo) outputs undefined. Once the function is assigned to foo, the second console.log(foo()) successfully calls the function, outputting "Hello!".

Concept:

  • Function Expressions and Hoisting: Only the variable declaration is hoisted, not the function body. The function is assigned later in the code execution.

7. Hoisting with const Declaration

Question:

console.log(b);
const b = 30;
Enter fullscreen mode Exit fullscreen mode

Output:

ReferenceError: Cannot access 'b' before initialization
Enter fullscreen mode Exit fullscreen mode

Explanation:

Like let, variables declared with const are hoisted but are in the temporal dead zone (TDZ) until initialized. Accessing b before it is initialized results in a ReferenceError.

Concept:

  • Hoisting and const: Variables declared with const are hoisted but are not accessible before initialization due to TDZ.

8. Hoisting with Function Declarations and Variable Declarations

Question:

function hoist() {
    console.log(a);
    var a = 10;
    console.log(a);
}

var a = 20;
hoist();
console.log(a);
Enter fullscreen mode Exit fullscreen mode

Output:

undefined
10
20
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • Inside hoist(), a is hoisted as a local variable, so console.log(a) prints undefined first. After assignment, a becomes 10. Outside the function, the global a is unaffected and retains its value of 20.
  • Hoisting ensures that the local a in hoist() is treated separately from the global a.

Concept:

  • Local vs Global Scope: Variable hoisting applies within function scope and does not affect the global scope.

9. Hoisting with Arrow Functions

Question:

console.log(foo);

var foo = () => {
    return "Arrow Function!";
};

console.log(foo());
Enter fullscreen mode Exit fullscreen mode

Output:

undefined
Arrow Function!
Enter fullscreen mode Exit fullscreen mode

Explanation:

Similar to function expressions, when using arrow functions, the variable foo is hoisted but remains undefined until it is initialized. So, the first console.log(foo) prints undefined, and the second console.log(foo()) works after foo is assigned the arrow function.

Concept:

  • Arrow Function Hoisting: Arrow functions behave like function expressions, where only the variable is hoisted, not the function body.

10. Hoisting with let and var in Loops

Question:

for (var i = 0; i < 3; i++) {
    setTimeout(() => console.log(i), 1000);
}

for (let j = 0; j < 3; j++) {
    setTimeout(() => console.log(j), 1000);
}
Enter fullscreen mode Exit fullscreen mode

Output:

3
3
3
0
1
2
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • For var i, the variable i is hoisted and shared across all iterations. By the time the setTimeout callback runs, the loop is done and i has the value 3.
  • For let j, let is block-scoped, so each iteration of the loop gets a new copy of j. Therefore, when the setTimeout callback runs, it prints the correct values (0, 1, 2).

Concept:

  • Loop Scoping with var vs let: Variables declared with var are hoisted and shared across loop iterations, while let creates a new binding for each iteration.

These output-based questions on hoisting will help you understand how JavaScript manages variable and function declarations in its execution context. Hoisting plays a crucial role in understanding the behavior of code, especially when dealing with var, let, const, and functions.

Top comments (0)