这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战
作用域
var声明的变量为函数作用域
let、const声明的变量为块级作用域
变量提升
var声明的变量存在变量提升(将变量提升到当前作用域的顶部)、函数提升。即变量可以在声明之前调用,值为undefined。
let和const不存在变量提升。即它们所声明的变量一定要在声明后使用,否则报ReferenceError错。
暂时性死区
let和const**存在暂时性死区。即只要块级作用域内存在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,b
for (const value of [1,2,3,4,5]) {
console.log(value);
}
```
通过let和const提升性能
相比于以函数为作用域的var,以块为作用域的let和const,在块作用域比函数作用域更早终止的情况下,这两个新关键字可能会更早的让垃圾回收程序介入,尽早回收应该回收的内存。