DEV Community

Cover image for "Master JavaScript Hoisting: 10 Tricky Output Questions Every Developer Must Know!" - Part 2
Hithesh__k
Hithesh__k

Posted on

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

Here are a few advanced hoisting-related questions that challenge your deeper understanding of JavaScript's execution context, closures, and async behavior:
link for part-1 of the series


11. Hoisting with Functions and var Declaration in the Same Name

Question:



var foo = 10;

function foo() {
console.log('I am a function');
}

console.log(foo);

Enter fullscreen mode Exit fullscreen mode




Output:




10

Enter fullscreen mode Exit fullscreen mode




Explanation:

When both a variable and a function are declared with the same name, the function declaration is hoisted first, but the variable assignment takes precedence during execution. So, the variable foo holds the value 10 and not the function.

Concept:

  • Function vs Variable Hoisting: Function declarations are hoisted first, but var variable assignments override them if declared later in the same scope.

12. Hoisting with Functions inside if Statements

Question:



if (true) {
function test() {
console.log('Inside function');
}
}

test();

Enter fullscreen mode Exit fullscreen mode




Output:




Inside function

Enter fullscreen mode Exit fullscreen mode




Explanation:

In most JavaScript engines, function declarations inside blocks (if, for, etc.) are hoisted to the top of their enclosing scope, making them available outside of the block. So, even though test() is declared inside an if block, it is hoisted and accessible outside the block.

Concept:

  • Function Hoisting inside Blocks: Functions inside blocks can still be hoisted to the top of their scope, though this behavior can differ between strict and non-strict mode.

13. Hoisting and Class Declarations

Question:



const obj = new MyClass();

class MyClass {
constructor() {
this.name = 'JavaScript';
}
}

Enter fullscreen mode Exit fullscreen mode




Output:




ReferenceError: Cannot access 'MyClass' before initialization

Enter fullscreen mode Exit fullscreen mode




Explanation:

Unlike functions, class declarations are not hoisted. They behave more like variables declared with let or const, where they are in a temporal dead zone until fully initialized. Accessing a class before its declaration will throw a ReferenceError.

Concept:

  • Class Hoisting: Class declarations are hoisted but are not initialized before their actual definition, meaning they cannot be accessed before they are declared.

14. Hoisting and Named Function Expressions

Question:



var foo = function bar() {
console.log(typeof bar);
};

foo();
console.log(typeof bar);

Enter fullscreen mode Exit fullscreen mode




Output:




function
undefined

Enter fullscreen mode Exit fullscreen mode




Explanation:

This example uses a named function expression. Inside the function expression, the name bar is available and refers to the function itself, but bar is not hoisted or available in the outer scope. So, typeof bar inside the function returns "function", while outside it returns undefined.

Concept:

  • Named Function Expression: Function names in expressions are not hoisted and are only accessible inside the function itself.

15. Hoisting with Async/Await and var

Question:



async function asyncTest() {
console.log(a);
var a = 10;
await new Promise(resolve => setTimeout(resolve, 1000));
console.log(a);
}

asyncTest();

Enter fullscreen mode Exit fullscreen mode




Output:




undefined
10

Enter fullscreen mode Exit fullscreen mode




Explanation:

This question combines hoisting with asynchronous code. The variable a is hoisted inside asyncTest() and is initialized as undefined at the start. After the await is resolved, the second console.log(a) prints 10, which was assigned before the asynchronous code was executed.

Concept:

  • Async/Await and Hoisting: Hoisting happens normally within async functions, and await simply pauses the execution without affecting the hoisting behavior.

16. Hoisting with var and Immediately Invoked Function Expressions (IIFE)

Question:



var a = 1;

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

console.log(a);

Enter fullscreen mode Exit fullscreen mode




Output:




undefined
2
1

Enter fullscreen mode Exit fullscreen mode




Explanation:

  • Inside the IIFE, var a = 2 hoists the variable declaration but not its assignment. So the first console.log(a) inside the function prints undefined.
  • The second console.log(a) prints 2 after the assignment.
  • Outside the IIFE, the global a remains unchanged and prints 1.

Concept:

  • Hoisting within IIFE: Each function (including IIFEs) has its own scope for hoisting. The outer a is unaffected by the hoisting inside the IIFE.

17. Hoisting and Function Expression inside a Block

Question:



{
var a = function() {
return 'I am a function';
};
}

console.log(a());

Enter fullscreen mode Exit fullscreen mode




Output:




I am a function

Enter fullscreen mode Exit fullscreen mode




Explanation:

In this example, var a is hoisted to the top of the surrounding scope, which is the global scope. The function expression is then assigned to a. So when console.log(a()) is called, it correctly executes the function and returns "I am a function".

Concept:

  • Function Expression Hoisting: The var declaration of the function is hoisted, making the function available in the surrounding scope, even if declared inside a block.

These advanced questions provide a deeper dive into hoisting, covering more complex scenarios like class declarations, async functions, and function expressions. Understanding these intricacies is crucial for mastering JavaScript and avoiding potential issues in your code.

Top comments (0)