js作用域三:let const 有变量提升吗?

1,739 阅读2分钟

let const 有变量提升吗?

开始的时候我简单的认为 let const 是没有变量提升的,直到我看到了下面这段代码和方应杭老师的这篇博文 我用了两个月的时间才理解 let

x = "global";
// function scope:
(function() {
    x; // not "global"

    var/let/… x;
}());
// block scope (not for `var`s):
{
    x; // not "global"

    let/const/… x;
}

代码解读

x = 'global';

// 函数作用域
(function () {
  console.log(x)
  var x = 1
})()
  1. console.log(x) 打印出来的不是 global,而是 undefined
  2. 说明 var 声明的 x 已经被提升了,如果没有被提升应该会顺着作用域链向上查找到 x = 'global'
x = 'global';

// 函数作用域
(function () {
  console.log(x)
  let x = 1
})()
  1. console.log(x) 打印出来的不是 global,而是控制台报错 Uncaught ReferenceError: Cannot access 'x' before initialization
  2. 说明 let 声明的 x 已经被提升了,只是存在临时死域,如果没有被提升应该会顺着作用域链向上查找到 x = 'global'
x = 'global'

// 块级作用域
{
  console.log(x)
  const x = 1
}
  1. constlet 都是控制台报错 Uncaught ReferenceError: Cannot access 'x' before initialization
  2. 说明 constlet 声明的 x 已经被提升了,只是存在临时死域,如果没有被提升应该会顺着作用域链向上查找到 x = 'global'

总结:

  1. let const 是有变量提升的,但是跟var 和 function 有区别。
  2. let const 有临时死域/临时死区

1. let const 是有变量提升的,但是跟var 和 function 有区别。

  1. var 的「创建」和「初始化」都被提升了。
  2. function 的「创建」「初始化」和「赋值」都被提升了。
  3. let 的「创建」过程被提升了,但是初始化没有提升。
  4. const 和 let 只有一个区别,那就是 const 只有「创建」和「初始化」,没有「赋值」过程。 这四点是直接抄了 我用了两个月的时间才理解 let 的答案, 但是我觉得 function 和 const 一样只有「创建」和「初始化」,没有「赋值」过程,(初始化即赋值),如果我这里理解有错误的话,请指正。

2. 什么是临时死域?

写 let/const 声明的那行到作用域顶端,变量在这个区间只是被「创建」还没「初始化」化,不能被使用,所以这个区间被成为临时死域。

let x = 'global'
{
  // 作用域顶端 x 的临时死域--start

  console.log(x) // Uncaught ReferenceError: Cannot access 'x' before initialization
  
  // x 的临时死域--end
  let x = 1
}

相关

参考