Search code examples
javascripthoisting

Whether the nested function hoisting affects the global variable (declared in the same function)?


var b = 4;
function f() {
  b = 7;
  return b;
}

a = f();
console.log(a); //output: 7
console.log(b); //output: 7

In the codes above, b = 7 makes b automatically global, thus changing the value of var b to 7. But when a nested function b is added as below, I am confused about the output result:

var b = 4;
function f() {
  b = 7;
  return b;
  function b() {}
}

a = f();
console.log(a); //output: 7
console.log(b); //output: 4

In my opinion, since function b is hoisting in function f, a reference to function b is first created on the activation object, and when we get the interpreter gets to b = 7, we already see the property name b exists so the code b = 7 does nothing and proceeds, thus console.log(b) outputs 4. But how come console.log(a) still outputs 7? b = 7 should do nothing here, right?


Solution

  • For the first block of code this assertion isn't accurate:

    In the codes above, b = 7 makes b automatically global, thus changing the value of var b to 7.

    In the statement b = 7, b is bound to that outer var b declaration, so b = 7 assigns to that b variable in the closure.

    In the second block of code, you have a misunderstanding of what hoisting does. Think of hoisting as simply moving a declaration to the top of its scope, so:

    function f() {
      b = 7;
      return b;
      function b() {}
    }
    

    ...behaves as though you did this:

    function f() {
      let b = function () { }
      b = 7;
      return b;
    }
    

    On the line b = 7, you're assigning a new value 7 to the local variable b. Hence return b; returns 7.