1

var x = 2;

function fun() {
  x = 3;
  var x = 4;
  document.write(x);
}

document.write(x);

fun()

document.write(x);

Can someone help me understand the flow of control. Why is the output 242 when it looks like output should be 243. All help will be greatly appreciated.

Andy
  • 61,948
  • 13
  • 68
  • 95
  • 3
    The `var` declaration in the function is interpreted as if it appeared at the very start of the function block. All references to `x` in the function are references to the local variable, not the global `x`. – Pointy Apr 12 '19 at 12:24
  • Are you sure of the answer? Sorry to ask. – iWIllChange Apr 12 '19 at 12:26
  • it's simple, just printed the output as per the scope of variable. – Devsi Odedra Apr 12 '19 at 12:26
  • Yes, I'm sure. You're seeing that it prints 242 right? – Pointy Apr 12 '19 at 12:27
  • thanks for the answer. it helped a lot ^_^ – iWIllChange Apr 12 '19 at 12:28
  • Hoisting is confusing. I would have expected 444. – Lewis Apr 12 '19 at 12:28
  • 2
    @Lewis Then you need to read about [scope](https://developer.mozilla.org/en-US/docs/Glossary/Scope). – Teemu Apr 12 '19 at 12:30
  • @Lewis It can't be **444**. The global variable is never changed. And its printed two times. So there will be two `2`s – Maheer Ali Apr 12 '19 at 12:31
  • @Maheer @Pointy - Thanks. I thought using `var` before x = 4 would have replaced `x = 2` when hoisted. I clearly misunderstand what `var` does. – Lewis Apr 12 '19 at 12:33
  • According to [link](https://www.w3schools.com/js/js_hoisting.asp) hoisting happens only in case of a declaration. In the question, it's initialised too. So is it hoisting that's happening? – iWIllChange Apr 12 '19 at 12:33
  • Yes, the declaration of `x` is hoisted in the function, and the global `x` is shadowed inside the function because of the hoisted declaration. – Teemu Apr 12 '19 at 12:34

2 Answers2

6

This due to hoisting. The variable x which is local inside fun is brought to top of scope and then assigned the value 3 and after that assign value 4. So line x=3; is not changing global variable but its changing local variable. The code acts like

function fun(){
    var x;
    x=3;
    x=4;
    document.write(x);
}
Maheer Ali
  • 35,834
  • 5
  • 42
  • 73
5

When you modify the x=3 it is not actually changing the global variable x but the variable declared in the function block (as var variables have function scope). As the declaration var x is hoisted to the top and then the modification to x = 3 happens

<script>
      var x=2;
      function fun(){
          //var x; hoisted to the top;
          console.log("x is hoisted here and uninitialized value will be", x)
   x=3; //initialized, actually referring to the variable declared in the function scope 
   var x = 4; //declared but hoisted at the top
   document.write(x);
 }
 document.write(x);
 fun()
 document.write(x);
</script>

To really change the variable at the global scope, use window.x to refer to it:

<script>
     var x=2;
     function fun(){
      window.x=3; //modifying the global variable 'x`
      var x = 4; 
      document.write(x);
     }
     document.write(x);
     fun()
     document.write(x);
</script>
Fullstack Guy
  • 16,368
  • 3
  • 29
  • 44