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

Shi*_*oni 1 javascript iife

此 IIFE 代码能够访问计数

let count = 0;
(function immediate() {
  if (count === 0) {
    let count = 1;
    console.log(count);
  }
  console.log(count);
})();
Run Code Online (Sandbox Code Playgroud)

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

var count = 0;
(function immediate() {
  if (count === 0) {
    var count = 1;
    console.log(count);
  }
  console.log(count);
})();
Run Code Online (Sandbox Code Playgroud)

Mar*_*ini 5

如果您使用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.
})();
Run Code Online (Sandbox Code Playgroud)

正如您所看到的, if块内的变量现在覆盖全局count

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

更新

感谢 @t.niese 的评论,我认为值得提及varletconst之间的另一个区别。

与var一样,letconst也被提升,但有以下区别:

  1. 它们有一个块作用域,而不是像var那样的函数作用域
  2. 它们被声明但没有像var那样初始化为undefined
  3. 任何在初始化之前访问使用letconst声明的变量的尝试都会导致ReferenceError异常,而访问未声明的变量或提升的var将仅返回undefined