var let const 关键字区别

245 阅读3分钟

这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战

作用域

var声明的变量为函数作用域

let、const声明的变量为块级作用域

变量提升

var声明的变量存在变量提升(将变量提升到当前作用域的顶部)、函数提升。即变量可以在声明之前调用,值为undefined。

let和const不存在变量提升。即它们所声明的变量一定要在声明后使用,否则报ReferenceError错。

暂时性死区

letconst**存在暂时性死区。即只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

```
var tmp = 123;
if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

```

以上代码if后面{}形成了块级作用域,由于使用let声明了tmp,则这个变量就绑定了块区域,在声明之前使用,会报错。

全局声明

var全局声明的变量会成为window对象的属性

let与const全局声明的变量不会成为window对象的属性

```
var name = 'Johnson';
window.name === name // true
​
let job = 'frontend';
window.job === job // false
```

重复声明变量

var允许重复声明变量

let和const在同一作用域不允许重复声明变量

变量覆盖

var声明变量,函数作用域,后面能覆盖之前声明的值

```
var price = 100
        var count = 10
        if (count > 5) {
            var discount = price * 0.6
            console.log(`the discount is ${discount}`)
        }
```

let 、const声明变量,块作用域,后面不能覆盖之前声明的值

```
var price = 100
        var count = 10
        if (count > 5) {
            let discount = price * 0.6
            console.log(`the discount is ${discount}`)
        }
```

条件声明(if、try/catch)

var可以使用条件声明变量

let和const使用条件声明变量是无效的

是否可以修改声明的变量

var和let可以声明一个只读的常量。声明时必须立即初始化。

const声明引用类型变量时,变量名不指向数据,而是指向数据所在地址,只保证变量名指向的地址不变。

for循环中let、const声明

let

for循环设置变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。

```
for (let i = 0; i < 5; i++) {
    console.log(i)
}
```

1.首先这个变量 _ i的作用域是在()里才有效的,循环体里是不能访问到 _ i的

2.每次循环的时候创建一个i变量,将括号里的_i赋值到变量i上 3.最后i++后再将变量i的值赋值回 _i上

const

不能用const声明迭代变量,因为迭代变量会自增。

可以使用const声明不会被修改的for循环变量,每次迭代只是创建一个新变量。

```
for (const key in {a:1,b:2}) {
    console.log(key);
}
//a,bfor (const value of [1,2,3,4,5]) {
    console.log(value);
}
```

通过let和const提升性能

相比于以函数为作用域的var,以块为作用域的let和const,在块作用域比函数作用域更早终止的情况下,这两个新关键字可能会更早的让垃圾回收程序介入,尽早回收应该回收的内存。