1. let
-
es6中新增的用于声明变量的关键字,let声明的变量只在所处于的块级有效,针对于es6新增的块级作用域
if (true) { let a = 1; } console.log(a);// a is not defined;
-
使用let声明的变量只能被声明一次
-
特别注意:一个块级作用域中存在子作用域,子作用域可以访问父作用域,但是父作用域不可以访问子作用域
if (true) { let a = 1; if (true) { let b = 1; console.log(a); // 1 } console.log(b); // b is not defined; }
-
注意:
- 使用var声明的变量不具备块级作用域特性,因此let变量的使用可以防止循环变量变成全局变量
for (var i = 0; i < 3; i++) { } console.log(i); // 3 // 外面可以访问 for (let i = 0; i < 3; i++) { } console.log(i); // i is not defined 外面不可以访问
-
使用let关键字声明的变量,不具有变量提升
-
使用let关键字声明的变量,具有暂时性死区特性,也即let声明的变量与块级作用域绑定,即使与外部变量同名,也没有相互的关系,因此以下代码会报错。
var a = 1; if (true) { console.log(a);// a is not defined let a; }
2. const
-
es6中新增用于声明常量的关键字,常量也即:变量所存储的内存地址不可修改
-
具有let所有的优点
-
具有的特性:
- 具有块级作用域
- 不存在变量提升
- 需要赋初值
- 值不可被修改
-
注意:
const声明的常量仅仅是指的是其所指向的值不可变,但是当const声明的常量指向对象/数组时,虽然可以不修改const常量的指向,但是可以对其所指向的对象的值进行修改。因此const并不能真正的保护数据不被改变。如果想要数据不被改变可以采取以下方式:
-
Object.freeze()
防止数据改变 -
采用以上方式,任何试图改变对象的方式都会被阻止,而不会报错
let obj = { uname: 'zt', age: 19 } Object.freeze(obj);// 冻结对象obj obj.uname = 'zztt';// 试图修改对象obj但是被忽略,实则并没有修改对象obj的值
-