Skip to content

Latest commit

 

History

History
186 lines (149 loc) · 3.15 KB

42.Hoisting-V.md

File metadata and controls

186 lines (149 loc) · 3.15 KB

42. Hoisting V

Problem

https://bigfrontend.dev/quiz/hoisting-v

Problem Description

What does the code snippet below output by console.log?

(() => {
  if (!fn) {
    function fn() {
      console.log('2');
    }
  }
  fn();
})();

function fn() {
  console.log('1');
}

// another one
function fn1() {
  console.log('3');
}

(() => {
  if (!fn1) {
    function fn1() {
      console.log('4');
    }
  }
  fn1();
})();

// another one !
(() => {
  if (false) {
    function fn3() {
      console.log('5');
    }
  }
  fn3();
})();

Answer

(() => {
  if (!fn) {
    function fn() {
      console.log('2');
    }
  }
  fn();
})();

function fn() {
  console.log('1');
}

// logs "2"

/* ------------------------------- */

// another one
function fn1() {
  console.log('3');
}

(() => {
  if (!fn1) {
    function fn1() {
      console.log('4');
    }
  }
  fn1();
})();

// logs "4"

/* ------------------------------- */

// another one !
(() => {
  if (false) {
    function fn3() {
      console.log('5');
    }
  }
  fn3();
})();

// logs Error

Explanation

(() => {
  if (!fn) {
    function fn() {
      console.log('2');
    }
  }
  fn();
})();

function fn() {
  console.log('1');
}

The code snippet above logs "2", because when a function is created conditionally, either the function name or the function declaration is hoisted to the top of the scope, no matter the if condition pass or not. Whether only the function name or the function declaration is hoisted to the top of the scope depends on the browser. In Chrome and Firefox, only the function name is hoisted, whereas in Safari, function declaration is hoisted:

var hoisted = 'foo' in this;
console.log(
  `'foo' name ${hoisted ? 'is' : 'is not'} hoisted. typeof foo is ${typeof foo}`
);
if (false) {
  function foo() {
    return 1;
  }
}

// In Chrome and Firefox:
// 'foo' name is hoisted. typeof foo is undefined
//
// In Edge:
// 'foo' name is not hoisted. typeof foo is undefined
//
// In Safari:
// 'foo' name is hoisted. typeof foo is function

/* ------------------------------------------------------ */

var hoisted = 'foo' in this;
console.log(
  `'foo' name ${hoisted ? 'is' : 'is not'} hoisted. typeof foo is ${typeof foo}`
);
if (true) {
  function foo() {
    return 1;
  }
}

// In Chrome and Firefox:
// 'foo' name is hoisted. typeof foo is undefined
//
// In Edge:
// 'foo' name is not hoisted. typeof foo is undefined
//
// In Safari:
// 'foo' name is hoisted. typeof foo is function

The same logic applies to the rest of the cases.

In addition, if you declare a var variable in a if statement, the variable declaration is also hoisted, no matter the if condition pass or not:

console.log(a); // undefined , not respond ReferenceError ,it has been hoisted
if (true) {
  var a = 1;
}
console.log(b); // same as above
if (false) {
  var b = 1;
}

Reference