JS中var、let和const的区别

305 阅读2分钟

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---