为什么 let 变量可以在 IIFE 中访问而 var 不能?

Why is let variable accessible within IIFE & var is not?

此 IIFE 代码能够访问 count

let count = 0;
(function immediate() {
  if (count === 0) {
    let count = 1;
    console.log(count);
  }
  console.log(count);
})();

但为什么在这种情况下 count 未定义?

var count = 0;
(function immediate() {
  if (count === 0) {
    var count = 1;
    console.log(count);
  }
  console.log(count);
})();

如果你使用 var 变量声明被提升,这意味着你的代码将按以下方式重写:

var count = 0;
(function immediate() {
  var count; // decalration of variable hoisted on the function scope
             // and the count variable now is undefined.
  if (count === 0) {
    count = 1;
    console.log(count);
  }
  console.log(count); // just this is printed.
})();

如您所见,if 块中的变量现在覆盖全局 count.

事实上,这种行为并不那么明显,这是许多人建议避免使用 var 的原因,因为我们可以使用 letconst 相反,它们具有块作用域。

更新

感谢@t.niese 的评论,我认为值得一提的是 varletconst.

varletconst 一样被挂起,但有以下区别:

  1. 它们有块作用域,没有var这样的函数作用域有
  2. 它们被声明但没有初始化为 undefined 就像 var
  3. 任何尝试在初始化之前访问使用 letconst 声明的变量将导致 ReferenceError 异常,在访问未声明的变量或提升的 var 时将 return 只是 undefined.