1

I am a bit confused here in the Variable Hoisting concept. Why does the first console.log(flag) outputs undefined? Shouldn't it catch the already initialised value of false moving up the scope chain?

var flag = false;
(function(){
    console.log(flag);
    var flag = true; // JavaScript only hoists declarations, not initialisations

    console.log(flag);

    if(flag){
        let name = "John";
        const age = "24";

        console.log(name);
        console.log(age);
    }

    //console.log(name); //ReferenceError: name is not defined ( as name is block scoped here )
    //console.log(age);  //ReferenceError: age is not defined ( as age is block scoped )

})();
Rohit Ambre
  • 921
  • 1
  • 11
  • 25
Rahul Sharma
  • 358
  • 2
  • 10
  • 3
    `var flag = true` is a separate declaration that shadows `var flag = false`. Since it's a different declaration, you will get the new one. But since the assignment hasn't run yet, you just get `undefined`. – VLAZ Jul 08 '20 at 07:08
  • 1
    Also relevant: ['Hoisted' JavaScript Variables](https://stackoverflow.com/q/29667199) [JavaScript hoisting explanation](https://stackoverflow.com/q/49873174) [Javascript function scoping and hoisting](https://stackoverflow.com/q/7506844) – VLAZ Jul 08 '20 at 07:13

3 Answers3

6

In JS we also have functional scope and since variable name is same in both scopes, the global flag gets overridden and because of that the first console.log(flag) outputs undefined. Considering this piece of code :

(function(){
console.log(flag);
var flag = true;
})

Applying Variable Hoisting concept this will internally become like this:

(function(){
var flag=undefined;
console.log(flag);
flag = true;
})

You are confused because of the outer scope flag variable but that will be overridden with the functional scope flag variable because of same naming conventions used.

kapil pandey
  • 1,853
  • 1
  • 13
  • 26
3

The flag is hosted inside IIFE

var flag = false;
(function(){
    var flag; // undefined
    console.log(flag);
    flag = true; // JavaScript only hoists declarations, not initializations

    console.log(flag);

    if(flag){
        let name = "John";
        const age = "24";

        console.log(name);
        console.log(age);
    }

    //console.log(name); //ReferenceError: name is not defined ( as name is block scoped here )
    //console.log(age);  //ReferenceError: age is not defined ( as age is block scoped )

})();
strdr4605
  • 3,796
  • 2
  • 16
  • 26
  • Because the value of the `flag` at first log is `undefined`. If you want to print `false` then you should remove second `var flag = ` declaration and leave it `flag = ` – strdr4605 Jul 08 '20 at 07:13
  • 1
    Oh, it is because only my flag declaration gets hoisted on top of the function. – Rahul Sharma Jul 08 '20 at 07:14
1

Here happens following:

Your declaration var flag = true; gets hoisted inside of its execution environment. In this case it is your function. Its kinda weird but only the declared variable gets hoisted without the value assignment.

var flag = false;
(function(){
    console.log(flag);
    var flag = true; // JavaScript only hoists declarations, not initializations

    console.log(flag);

    if(flag){
        let name = "John";
        const age = "24";

        console.log(name);
        console.log(age);
    }

    //console.log(name); //ReferenceError: name is not defined ( as name is block scoped here )
    //console.log(age);  //ReferenceError: age is not defined ( as age is block scoped )

})();
bill.gates
  • 14,145
  • 3
  • 19
  • 47