与var对应,ES6新增两种声明变量的关键字let和const,本篇用来记录其特性
1.块级作用域
var声明的变量作用域为函数作用域,如下所示:
function getNum(){
var num = 10;
console.log(num);//10
}
getNum();
console.log(num);//referenceError
let和const声明的变量作用域为块级作用域,块级作用域,即 {}
{
let num = 10;
console.log(num);//10
}
console.log(num);//referenceError
2.变量重新赋值
let声明的变量可像var一样重新赋值,而const则不可以
let num = 10;
num = 20;
console.log(num);//20
const age = 10;
age = 20;
console.log(age);//TypeError
但当const声明对象时,有一种情况可以改变变量值
const people = {
name: 'Tom',
age: 20
}
people = { name: 'Jary' }//TypeError
people.name = 'Jary';//success
当使用第二种方法时,people的name就会成功改变,这是因为对象是引用类型,people只是一个指针,第一种方法是修改了指针的指向,不能成功,而第二种方法改变的是对象的属性,成功,也就是说const只能让指针的指向不发生改变,而修改其属性则可以实现。
3.let在for循环的运用
let因为是块级作用域,所以它只作用在for语句之中
for (var i = 0; i < 3; i++) {
console.log(i);//0 1 2
}
console.log(i);//3
for (let i = 0; i < 3; i++) {
console.log(i);//0 1 2
}
console.log(i);//referenceError
当使用var定义i时,在for中使用setTimeout方法时他会输出循环的最后一次,而使用let则可以解决这个问题
for (var i = 0; i < 3; i++) {
setTimeout(function(){
console.log(i);//3 3 3
},1000)
}
for (let i = 0; i < 3; i++) {
setTimeout(function(){
console.log(i);//0 1 2
},1000)
}
这是因为var声明的变量其实作用域为全局作用域中,setTimeout方法是在1秒后执行,而此时for早早就已经完成循环,i变为了3,之后执行时则会出现三个3;
而let作用域在for内,所以每次setTimeout输出的是我们想要得到的结果
4暂时性死区
在使用var时,会有下面这个问题
console.log(name);
var name = 'Tom';
此时结果是undefined,这是因为var具有变量提升的作用,这段真正的执行顺序应该是下面这样
var name;
console.log(name);
name = 'Tom';
而如果使用let或const声明的变量,虽然也是会变量提升,但是它还具有一个暂时性死区的特性
console.log(name);//referenceError
let name = 'Tom';
暂时性死区即在声明变量之前使用它,它虽然会变量提升,但是它会处于小黑屋中,与外界得不到联系