# Hoisting in JavaScript Practice Question

📗 **What is Hoisting in JavaScript?**

In JavaScript, **<mark>hoisting</mark>** <mark>is a behavior where </mark> **<mark>variables</mark>** <mark>and </mark> **<mark>functions</mark>** <mark>can be accessed even before they are initialised</mark>. This is because, during the creation phase of the JavaScript execution context, all the **variables** are allocated memory with an initial value of **undefined**, and the entire function code is also placed in the **execution context**.

When we try to access a variable during the code execution phase, it will contain the variable with an **undefined** value. Similarly, when we invoke a function, the whole code of the function is present, and it will work as expected.

Even **let** and **const** variables are **hoisted**, but they are placed in the **Temporal Dead Zone** until they are initialized. This means that an **error** is thrown when we try to access them before they are initialized.

*In summary, hoisting is a feature of JavaScript that allows variables and functions to be accessed before they are declared, but it's important to note that* ***let*** *and* ***const*** *variables are hoisted differently, and accessing them before initialization can result in an error.*

**Question 1**.

```javascript
    console.log(y);
    y = 1;
    --------------------------
    
    console.log(y);
    var y = 2;
    -------------------------
    
    y = 3;
    console.log(y);
    var y



// Output: 🤔
// ReferenceError: y is not defined
// undefined
// 3
```

**Explanation:** **Behind the scene, JavaScript interprets the above code as:**

```javascript

    console.log(y); // ReferenceError: y is not defined
    y = 1;
    -------------------
    
    var y = undefined;
    console.log(y); // undefined
    y = 2;
    -------------------
    
    var y = undefined;
    y = 3;
    console.log(y); // 3
```

**Question 2:**

```javascript
    var a = 1;
    console.log(a);
    
    var a = 2;
    console.log(a);


// Output: 🤔
// 1
// 2
```

**Explanation: Behind the scene, JavaScript interprets above code as:**

```javascript
    var a = undefined;
    a = 1;
    console.log(a); // 1
    
    a = 2;
    console.log(a); // 2
```

**Question 3:**

```javascript
    var z = 1;
    let z;
    console.log(z);
    
    -----------------
    
    console.log(z);
    let z = 1;



// Output: 🤔 
// Identifier ‘z’ has already been declared Cannot access ‘z’ before  initialization
```

**Explanation: Behind the scene, JavaScript interprets above code as:**

```javascript
    var z = 1;
    let z; //   SyntaxError: Identifier ‘z’ has already been declared
    console.log(z);
    
    -----------------
    
    let z;
    console.log(z); //  ReferenceError: Cannot access ‘z’ before
                    //  initialization
    z = 1;
```

**Question 4:**

```javascript
    function hoistExample() {
        var a;
        console.log("Before: ", a);
        a = 10;
        console.log("After: ", a);
    }
    hoistExample();

// Output: 🤔
// Before: Undefined
// After: 10
```

**Explanation: Behind the scene, JavaScript interprets above code as:**

```javascript
    function hoistingExample() {
        var a = undefined;
        console.log("Before: ", a);  // undefined
        a = 10;
        console.log("After: ", a); // 10
    }
    hoistingExample();
```

**Question 5:**

```javascript
    function hoistingExample() {
        console.log("Value of a in local scope: ", a);
    }
    console.log("Value of a in global scope: ", a);
    var a = 1;
    hoistingExample();



// Output: 🤔
// Value of an in global scope: Undefined Value of an in local scope: 1
```

**Explanation:**

When the code runs, it first declares a variable a in the global scope using the var keyword, but it does not assign a value to it yet. Then it calls the **hoistingExample()** function.

Inside the function, it tries to log the value of an in the local scope, but at this point, a is **undefined** because it has not been assigned a value yet.

After the **function declaration,** the code logs the value of an in the global scope, which is still **undefined** at this point.

Finally, the code assigns the value of **1** to the variable.

So when the **hoistingExample**() function is called, it logs **undefined** for the value of an in the local scope, but after the function is called, the value of an in the global scope has been updated to 1.

**Question 6:**

```javascript
    function hoistingExample() {
        a = 1;
    }
    hoistingExample();
    console.log(a);
    
    ----------------------------
    
    function hoistingExample() {
        var a = 1;
    }
    hoistingExample();
    console.log(a);


// Output: 🤔 
// 1 ReferenceError: a is not defined
```

**Explanation:**

In the first code snippet, the variable a is not declared with the **var, let, or const** keyword. Therefore, it will be automatically declared in the global scope and assigned the value of 1 inside the **hoistingExample**() function. When **console.log(a)** is executed outside of the function, it will **output 1** since **a** is in the global scope and has not been reassigned.

In the second code snippet, the variable a is declared using the var keyword inside the **hoistingExample**() function. This means that **a** is only accessible within the function's local scope and cannot be accessed outside of it. Therefore, when **console.log(a)** is executed outside of the function, it will result in a **reference error** since a is **undefined** in the global scope.

**Question 7:**

```javascript
    function a(){
        console.log("1")
    }
    a();
    
    function a(){
        console.log("2")
    }
    a();




// Output: 🤔
// 2 
// 2
```

**Explanation**: Behind the scene, JavaScript interprets above code as:

```javascript
    function a(){
        console.log("1")
    }
    function a(){
        console.log("2")
    }
    a(); // 2
    a(); // 2
```

When two function declarations of the same name are defined in the same scope, the second one will overwrite the first. In this case, the second **a() declaration** outputs **2** to the console, so when **a()** is called after the second declaration, it will execute the updated code block and output 2.

**Question 8:**

```javascript
    var test = 1;
    function functionHoisting() {
        test = 10;
        return;
        function test() {}
    }
    functionHoisting();
    console.log(test);



// Output: 🤔
// 1
```

**Explanation**:

The reason for this output is that the function declaration of test() inside the functionHoisting() function has no effect due to the return statement that immediately follows it.

When **functionHoisting()** is called, it sets the value of the global variable test to 10. However, the function declaration of test() inside the function does not change the value of the global test variable. This is because the function declaration is hoisted to the top of the function scope, but it is never actually called or executed.

Therefore, when **console.log(test)** is executed outside of the function, it outputs the original value of **1** that was set at the beginning of the program, rather than the updated value of 10 that was set inside **functionHoisting()**.

**Question 9:**

```javascript
    
    console.log(a());
    
    function a() {
        var b = function () {
            return 3;
        };
        return b();
        var b = function () {
            return 8;
        };
    }

    -------------------------------------------------------------

    console.log(a());
    function a() {
        var b = function () {
            return 3;
        };

        var b = function () {
            return 8;
        };

        return b();

    }



// Output: 🤔 
// 3 
// 8
```

**Explanation:**

In the first snippet, the function defines a variable **b** with a function expression that returns 3. This is followed by a return statement that immediately invokes the **b** function and returns its result.

The second function expression that returns 8 is never executed because it is defined after the return statement. So, the b function that is returned and invoked is the one that returns 3.

Therefore, console.log(a()) will log 3 to the console.

In the second snippet, When **a()** is called, it returns the value of the function **b()**. However, the **b()** function that is returned is the second b() function, which returns the value 8. This is because the second **b()** function is defined after the first **b()** function, so it "overrides" the first **b()** function.

Therefore, when **a()** is called, it returns the value **8**

**Question 10:**

```javascript
    var temp= 'hi';
    function display(){
         console.log(temp);
         var temp = 'bye';
    };
    display();



// Output:
// undefined
```

**Explanation**:

Within the **display()** function, there is a variable named **temp** that is declared using the **var** keyword. When the **console.log(temp)** statement is executed, the JavaScript interpreter looks for the value of **temp** within the local scope of the **display()** function.

However, since the **temp** variable is declared using var, it is hoisted to the top of the function scope. This means that the variable is technically declared before it is assigned a value. So, when **console.log(temp)** is called, the temp variable exists within the local scope of **display()**, but it has not yet been assigned a value.

As a result, the value of temp at this point is **undefined.**

**Thanks for reading it 😊. I hope it was insightful and that we got to learn something new today. If you liked the post, please post likes and share it in your circles. Share your feedback and comment away.**
