js常用的变量声明有方式 var、let 和 const,那它们之间到底有什么区别呢?什么是提升?什么又是暂时性死区?
1、var
对于这个问题,先来了解一下提升(hoisting)这个概念
console.log(age); // undefined
var age = 18;
从上述代码中可以发现,虽然变量还没有被声明,但是却可以使用到这个未被声明的变量,这种情况就叫提升,而且提升的是声明。
将代码这样来看,就一目了然了
var age
console.log(age); // undefined
age = 18;
再来看一个例子:
var age = 18;
var age;
console.log(age); // -> ?
如果还认为打印的是 undefined 那么就错了,真正打印的是 18,对于这种情况可以这样来看
var age;
var age;
age = 18;
console.log(age);
现在可以得出结论,var声明的变量会发生提升的情况,俗称变量声明的提升,不仅仅变量会提升,函数也会被提升。
console.log(fun); // ƒ fun() {}
function fun() {};
var fun = 1;
对于上述代码,打印结果会是 ƒ fun() {},即使变量声明在函数之后,这也说明了函数会被提升,并且优先与变量提升。
因此,还可以从中知道使用 var 声明的变量会被提升到作用域的顶部。
2、let 和 const
关于 let 和 const,再来看一个例子:
var a = 1;
let b = 1;
const c = 1;
console.log(window.b) // undefined
console.log(window.c) // undefined
function test() {
console.log(a);
let a;
};
test();
首先在全局作用域下使用 let 和 const 声明变量,变量并不会被挂载到 window 上(var声明的变量会),这是和 var 声明的区别之一。
接下来当在声明 a 之前如果使用了 a ,就会出现报错的情况
关于这个报错情况,首先报错的原因是因为存在暂时性死区,所以不能在声明前就使用变量,这也是 let 和 const 优于 var 的一点。虽然变量编译的环节中别告知在这块作用域中可以访问,但是访问是首先的。
思考:为什么会存在提升的这个事情呢?
其实根本原因提升是为了解决函数之间互相调用的情况
function fun1() {
fun2();
};
function fun2() {
fun1();
};
fun1();
如果没有提升,那么就实现不了上诉代码,因为没有提升就不存在fun1在fun2前面,然后fun2在fun1前面。
3、总结
-
var 存在提升,可以在声明之前使用变量。let 和 const 因为存在暂时性死区,所以不能在声明之前使用
-
var 在全局作用域下声明变量会导致变挂载在 window 上,而let 和 const 就不会
-
函数的提升优先于变量的提升,函数提升会把整个函数挪到作用域顶部,变量提升只会把声明挪到作用域顶部
-
let 和 const 作用基本一致,不同的是 cosnt 声明的变量不能再次赋值
---END---