let到底会不会造成变量提升

let到底会不会造成变量提升呢?
关于这个问题,大家可以先在心中想想现在自己的答案,我们继续往下看:

今天有个群里有人提了这个问题,大部分人都说不会,但是在我的印象里是觉得会的,但是太多不同的声音,让我也开始怀疑自己,到底会不会提升呢?

于是我又翻起了红宝书,在红宝书(第四版)第26页,有这么一句话:

let 与 var 的另一个重要的区别,就是 let 声明的变量不会在作用域中被提升。

但是在往后翻翻,在第92页又写了这么一句话:

严格来讲,let 在 JavaScript 运行时中也会被提升,但由于“暂时性死区”(temporal dead zone)的 缘故,实际上不能在声明之前使用 let 变量。因此,从写 JavaScript 代码的角度说,let 的提升跟 var 是不一样的。

所以到底存不存在提升呢?

我们先了解下什么是暂时性死区:
通过let或者const声明的变量会在进入块级作用域的时被创建,但是在该变量没有赋值之前,引用该变量JavaScript引擎会抛出错误。这就是“暂时性死区”。

我们再来看看ecma中对let和const的定义

let and const declarations define variables that are scoped to the running execution context’s LexicalEnvironment. The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated. A variable defined by a LexicalBinding with an Initializer is assigned the value of its Initializer’s AssignmentExpression when the LexicalBinding is evaluated, not when the variable is created. If a LexicalBinding in a let declaration does not have an Initializer the variable is assigned the value undefined when the LexicalBinding is evaluated.

我们重点看第二句:
The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated.(这些变量是在实例化包含它们的词法环境时创建的,但在评估变量的词法绑定之前,不得以任何方式访问它们。)

这里再拓展下:在一个执行上下文中,通过 var 声明的变量,在编译阶段全都被存放到变量环境里面了。通过 let 声明的变量,在编译阶段会被存放到词法环境(Lexical Environment)中。

我们再来看这一段代码:

function test(){
    console.log(a);
    let a = 1;
}

执行test的时候,编译阶段a已经在内存中,为什么提前访问不了?这主要是因为V8虚拟机做了限制,虽然a在内存中,但是当你在let a 之前访问a时,根据ECMAScript定义,虚拟机会阻止的访问。

最后总结下:
在块作用域内,let声明的变量被提升,但变量只是创建被提升,初始化并没有被提升,在初始化之前使用变量,就会形成一个暂时性死区。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值