块级作用域:代码执行时遇到花括号,会创建一个块级作用域,花括号结束,块级作用域销毁
使用var声明变量
- 有全局作用域和函数作用域的概念,没有块级作用域的概念
- 不初始化值默认为undefined
- 允许重复的变量声明:导致数据被覆盖
- 存在变量提升:怪异的数据访问、闭包问题
- 全局作用域用var声明的变量会挂载到全局对象window上:全局对象成员污染问题
使用let声明变量
-
没有全局作用域和函数作用域,有块级作用域
-
let 声明的变量不会挂载到全局上
-
let 声明的变量不允许在当前作用域范围内重复声明(块级绑定)
-
在块级作用域中用let定义的变量,在作用域外不能访问
- 在循环中,用 let 声明的循环变量会特殊处理,在每一次进入循环体,都会开启一个新的作用域,并且将循环变量绑定到该作用域
-
使用 let 不会有变量提升,因此不能在定义 let 变量之前使用它
- 底层实现上,let 声明的变量也会有提升,但是提升后会将其放入到暂时性死区,如果访问的变量位于暂时性死区,会报错,大致意思是:没有初始化之前不能使用这个变量
- 当代码运行到该变量的声明语句时,会将其从暂时性死区移出
使用const声明常量
const 和 let 的唯一区别:用 const 声明的变量,必须在声明时赋值,而且不可以重新赋值 实际上,在开发中,应该尽量使用const来声明变量,以保证变量的值不会随意篡改,原因如下:
- 根据经验,开发中很多变量都是不会更改,也是不应该更改的
注意的细节:
-
常量不可变,是指声明的常量的内存空间不可变,并不保证内存空间中的地址指向的其他空间不可变
const a = { name: 'zhang', age: 12, }; a.name = 'wang'; -
常量的命名
- 特殊的常量:该常量从字面意义上,一定是不可变的,比如圆周率、月地距离或其他一些绝不可能变化的配置。通常该常量的名称全部使用大写,多个单词用下划线分割
const PI = 3.14 cosnt MOON_EARTH = 99999; - 普通的常量:使用小驼峰命名即可
- 特殊的常量:该常量从字面意义上,一定是不可变的,比如圆周率、月地距离或其他一些绝不可能变化的配置。通常该常量的名称全部使用大写,多个单词用下划线分割
-
在for of循环中,循环变量,不能用 const 声明
-
在for in 循环中,循环变量可以用 const 声明
const obj = { name: 'lei', age: 1, }; for (const prop in obj) { console.log(prop); };