let 是否存在变量提升?

580 阅读2分钟

「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。

我的下意识回答是:不会; 找了相关的资料以及通过代码验证,发现自己还是太单纯。

首先,看看var在函数中执行的顺序

function myVar(){
   console.log(my_name)  //undefined
   var my_name = '嘻嘻嘻'
}

执行上叙代码的执行顺序是:

  1. 为myVar函数创建环境;
  2. 找到所有var定义的变量并创建(创建my_name);
  3. 给var定义的变量初始化为underfined (my_name = underfined);
  4. 执行代码
  5. 给var定义的变量赋值(my_name=‘嘻嘻嘻’);

然后看看let定义的块的执行顺序:

  let my_name='哈哈哈';
  function myVar(){
       console.log(my_name)  //哈哈哈
    }

上叙的代码因为函数的作用域,my_name 在所在函数查找,所在作用域没有,则往上查看,所以拿到外部作用域的'哈哈哈'

 let my_name='哈哈哈';
  function myVar(){
     console.log(my_name)  //Cannot access 'my_name' before initialization
     let my_name = '嘻嘻嘻'my_name = '嗯嗯嗯';
    }
    

而上面的代码在console.log(my_name) 后面多了let的定义,报了个 Cannot access 'my_name' before initialization 的错;如果不提升的话应该跟上一个函数报的是underfined的; 其实,let 所在的块的执行顺序是:

  1. 为块创建环境;
  2. 找到所有用let 定义的变量,并创建(创建my_name);
  3. 执行代码
  4. 给let 定义的变量初始化为'嘻嘻嘻';如果没有则初始化为underfined;
  5. 给let 定义的变量赋值 (my_name='嗯嗯嗯'); 这就解释了为什么在let定义之前报错, 原因有两个:
  6. console.log(my_name)的变量是let 定义的,不是全局的;
  7. 执行console.log(my_name)时,变量my_name还没有初始化(也就是所谓的暂时死区)

对比let 跟var的执行顺序可知:

  • var定义的变量在创建和初始化的阶段有提升;
  • let定义的变量在创建的时候有提升;

最后看 const,其实 const 和 let 只有一个区别,那就是 const 只有创建和初始化,没有赋值过程。