ES6 新增了let命令和const命令用于声明变量,用法类似于var,但是又有所不同,下面来具体介绍一下他们的用法和规则。
一、let
1、不允许重复声明
//1.不允许重复声明
var tt = 345;
var tt = 456;//tt 456
let rr = 234;
let rr = 'df';//Identifier 'rr' has already been declared
2、声明的变量只在声明所在的块级作用域内有效
//2.声明的变量只在声明所在的块级作用域内有效
eg1:
{
let a = 'a';
var b = 'b';
}
console.log(a);//会报错 a is not defined
console.log(b);//'b'
eg2:
var arr1 = [];
for (var i = 0; i < 10; i++) {//i属于全局
arr1[i] = function () {
console.log(i);
}
}
arr1[6](); //10 循环结束后i已经变成10
var arr2 = [];
for (let j = 0; j < 10; j++) {//使用let,声明的变量仅在块级作用域内有效
arr2[j] = function () {
console.log(j);
}
}
arr2[6](); //6
/* 另外,for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,
而循环体内部是一个单独的子作用域
*/
eg3:
for (let i = 0; i < 3; i++) {
let i = 'abc';
console.log(i);//输出三个'abc'
}
3、暂时性死区 TDZ
ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。也就是说使用let声明变量之前,该变量都是不可用的。在语法上称之为暂时性死区。
//3.暂时性死区 TDZ
eg1:
var t = 123;
if (true) {
t = 'rrr'; // ReferenceError 在声明之前使用
let t;
}
eg2:
let h = h;
// ReferenceError: x is not defined
//暂时性死区的原因 先执行右边的部分的h,但是此时还没执行let h,所以h还处于TDZ中
eg3:
if (true) {
// TDZ开始
y = 'abc'; // ReferenceError
console.log(y); // ReferenceError
let y; // TDZ结束
console.log(y); // undefined
y= 123;
console.log(y); // 123
}
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
4、不存在变量声明提升
console.log(bar); // 报错ReferenceError 在声明之前使用
let bar = 2;
5、声明的全局变量,不属于顶层对象的属性
let kk = 'kk';
console.log(window.kk);//undefined
二、const
上面的let的使用规则同样适用于const,但是const还有自己的一些规则。
1、声明一个只读的常量。一旦声明,常量的值就不能改变
1.一旦声明,常量的值就不能改变
const PI = 3.1415;
console.log(PI) // 3.1415
PI = 'PI'; // TypeError: Assignment to constant variable.
但是其本质是并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于原始值类型的数据,值就保存在变量指向的地址中;对于引用值类型的数据,变量指向的内存地址,保存的只是一个指向实际数据的指针。
const obj = {};
obj.name = 'test';
console.log(obj);//{name: "test"}
2、声明必须初始化
//2.声明时必须初始化
const year; //SyntaxError: Missing initializer in const declaration
现在来总结一下let和const的用法规则
1. let和const不允许重复声明
2. let和const声明的变量只在声明所在的块级作用域内有效
3. let和const变量声明不提前,存在暂时性死区
4. let和const声明的全局变量,不属于顶层对象的属性
5. const声明的变量指向的内存地址所保存的数据不得改动
6. const声明变量必须初始化
参考:let和const命令