var/let/const变量提升

var声明的创建、初始化和赋值过程
console.log(a);
var a = 1;

在执行过程中,会有以下过程:

  1. 在全局环境中创建用var声明的这些变量,即a
  2. 将这些变量初始化为undefined
  3. 执行console.log(a)
  4. a = 1将变量为1
let/const声明的创建、初始化和赋值过程
{
	let x = 1;
	x = 2;
}
  1. 找到所有用let声明的变量,在环境中创建这些便利
  2. 开始执行变量(注意现在还没有初始化)
  3. 执行x = 1,将x初始化为1(这并不是一次赋值,如果代码是let x,就将x初始化为undefined)
  4. 执行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);
}
  1. 找到所有用function声明的变量,在环境中创建这些变量
  2. 将这些变量初始化并赋值为function(){console.log(2)}
  3. 开始执行fn2()

猜你喜欢

转载自blog.csdn.net/csm0912/article/details/82754786