对 var、let、const 的一些研究:重复声明 | 变量提升 | 暂时性死区
【省流】三者的区别
(还没整理)
现象观察
在用 VS Code 尝试这三种变量的重复声明时,发现了一些很神奇的情况:
-
这种情况下,执行前不会预报任何错误,but 执行后会报错:
Identifier ‘a’ has already been declared.
——这里指的是 let 类型中,同一变量不能重复声明。
1
2
3
4
5
6
7
8
9
10
var a = 1;
var a = 2;
let a = 1;
let a = 2;
// const a = 1;
let b = a;
console.log(a);
- 但这种情况,IDE 就会给你报错:
“无法重新声明块范围变量“a”。”
—— typescript 语法检查的启用真是神奇(什么)
1
2
3
4
5
6
7
8
9
10
// var a = 1;
// var a = 2;
let a = 1;
let a = 2;
// const a = 1;
let b = a;
console.log(a);
- 这种情况,IDE 是能正常执行的:
最后会正常打印 “2” 的值。
1
2
3
4
5
6
7
8
9
10
var a = 1;
var a = 2;
// let a = 1;
// let a = 2;
// const a = 1;
let b = a;
console.log(a);
现象解释:var VS let 的变量声明
它们都各自干了什么,导致一个会报错、另一个却不会报错?
- 当使用
var重复声明一个变量时,JavaScript 解释器会将其视为对同一个变量的重新绑定,而不是一个新的声明。- 如果新的声明没有提供初始化器,它实际上什么都不做,只是维持现有变量的值。
- 如果新的声明提供了初始化器,那么该变量的值会更新为新初始化器提供的值。
变量提升 & 暂时性死区
道理很简单粗暴,但之前没看过的话就会一眼懵的那种。
或许我们还能从另一方面考虑,对于var声明的变量,它存在着变量提升,即无论你在何处用var声明变量,系统会自动将该变量的声明提升到当前作用域的顶部。
let声明的变量同样存在变量提升;但对于let声明的变量,则存在另一种特性:暂时性死区。let声明的变量会“绑定”当前作用域,如果在此let声明之前使用该变量,则会抛出错误,即形成暂时性死区(就是不能在声明之外/之前提前使用)。
(在 “从块作用域开始、到 let 变量声明,这块区域是 ‘禁区 / 死区’ ,不能使用该 let 变量”。)
作者:止曰链接:https://juejin.cn/post/7033001234709610509来源:稀土掘金著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- 所以可以利用 var 的变量提升,在??中先使用、后声明。
——但要注意的是,var 类型的变量提升提升的只有声明,而赋值是仍然滞后的。
比如这段代码,输出为 undefined:
1
2
console.log(myVar); // 输出:undefined
var myVar = 10;
let和const声明的变量也会提升,但它们不会被初始化,所以在提升后会处于一个所谓的暂时性死区(Temporal Dead Zone,TDZ),直到声明被实际执行。 如果在TDZ中访问这些变量,将会抛出一个引用错误。 ——let真的没有变量提升吗?let暂时性死区引发的思考 - CSDN博客
【补充】函数作用域 VS 块作用域
1. 具体区别
用 var 声明的变量的作用域是它当前的执行上下文,即如果是在任何函数外面,则是全局执行上下文,如果在函数里面,则是当前函数执行上下文。换句话说,var 声明的变量的作用域只能是全局或者整个函数块的。
2. 产生区别的原因
-
var 产生的历史背景:
JavaScript 诞生时只有 10 天的设计周期,Brendan Eich 为了快速让 JS 能运行在浏览器里,借鉴了 C/Java 语法和 Scheme 的部分思想。
所以你能感受到,“变量提升” 中的声明提前(在函数级别预先声明)这一点,和 C 特别像。
——然后就渐渐出现了 “历史遗留” 问题:
- 随着项目规模增大,人们发现:
var没有块级作用域,for循环里声明的变量会泄露到外层。- 变量提升让代码 可读性差、容易出 bug。
-
于是开发者社区常用“闭包技巧”或 IIFE(立即执行函数表达式)模拟块级作用域。
1 2 3 4 5 6 7
(function() { var i; for (i = 0; i < 3; i++) { console.log(i); } })(); console.log(i); // ReferenceError
- 随着项目规模增大,人们发现: