var声明的创建、初始化和赋值过程
console.log(a);
var a = 1;
在执行过程中,会有以下过程:
- 在全局环境中创建用var声明的这些变量,即a
- 将这些变量初始化为undefined
- 执行console.log(a)
- a = 1将变量为1
let/const声明的创建、初始化和赋值过程
{
let x = 1;
x = 2;
}
- 找到所有用let声明的变量,在环境中创建这些便利
- 开始执行变量(注意现在还没有初始化)
- 执行x = 1,将x初始化为1(这并不是一次赋值,如果代码是let x,就将x初始化为undefined)
- 执行x = 2,对x进行赋值
x = 1;
function test(){
console.log(x); // Uncaught ReferenceError: x is not defined
let x = 2;
}
test()
所以我理解为let/const是存在变量提升的(我的理解:如果let/const不存在变量提升,那么在let定义之前访问的x应该是全局定义的x即1),只是因为let/const存在一个暂时性死区所以在初始化之前无法访问:
The variables are created when their containing Lexical Environment is instantiated but may not be accessed inany way until the variable’s LexicalBinding is evaluated.
翻译成中文:
当程序的控制流程在新的作用域(module function 或 block 作用域)进行实例化时,在此作用域中用let/const声明的变量会先在作用域中被创建出来,但因此时还未进行词法绑定,所以是不能被访问的,如果访问就会抛出错误。因此,在这运行流程进入作用域创建变量,到变量可以被访问之间的这一段时间,就称之为暂时性死区。
function声明的创建、初始化和赋值过程
f2()
function fn2(){
console.log(2);
}
- 找到所有用function声明的变量,在环境中创建这些变量
- 将这些变量初始化并赋值为function(){console.log(2)}
- 开始执行fn2()