「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。
我的下意识回答是:不会; 找了相关的资料以及通过代码验证,发现自己还是太单纯。
首先,看看var在函数中执行的顺序:
function myVar(){
console.log(my_name) //undefined
var my_name = '嘻嘻嘻'
}
执行上叙代码的执行顺序是:
- 为myVar函数创建环境;
- 找到所有var定义的变量并创建(创建my_name);
- 给var定义的变量初始化为underfined (my_name = underfined);
- 执行代码
- 给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 所在的块的执行顺序是:
- 为块创建环境;
- 找到所有用let 定义的变量,并创建(创建my_name);
- 执行代码;
- 给let 定义的变量初始化为'嘻嘻嘻';如果没有则初始化为underfined;
- 给let 定义的变量赋值 (my_name='嗯嗯嗯'); 这就解释了为什么在let定义之前报错, 原因有两个:
- console.log(my_name)的变量是let 定义的,不是全局的;
- 执行console.log(my_name)时,变量my_name还没有初始化(也就是所谓的暂时死区)
对比let 跟var的执行顺序可知:
- var定义的变量在创建和初始化的阶段有提升;
- let定义的变量在创建的时候有提升;
最后看 const,其实 const 和 let 只有一个区别,那就是 const 只有创建和初始化,没有赋值过程。