ECMAScript6(ES6)标准之let、const关键字与块级作用域

隔了两周没有更新
今天开始整理ES6的知识
先来看看ES6增加的两个声明变量的关键字
let与const

块级作用域

我以前就写过一篇文章介绍了作用域的分类
传送门:理清JS中的词法、静态、动态、函数、块作用域
里面就谈到了块级作用域
在ES6之前
我们声明变量只能用var
并且作用域的机制是函数作用域(with关键字、catch子句是特例)

if(true){
    var i = 1;
}
console.log(i); //输出:1
(function foo(){
    var a = 1;
})();
console.log(a); //报错:a is not defined

(C/C++的作用域模式是块作用域)
ES6新增的let与const就可以将变量绑定到所在的任意作用域中(一般是 {….} 内部)
也就是说,let、const为声明的变量隐式劫持了所在的块作用域
与函数作用域类似
“块”内可以使用“块”外的变量
“块”外不能使用“块”内的变量

{
    var a = 1;
    let b = 2;
}
console.log(a); //1
console.log(b); //报错

let

上面我们复习了一下什么是块作用域
下面再来接着看看let产生的块级作用域有什么特点和优点

首先最重要的一点就是
使用let声明 不会有提升行为
下面就是var和let的区别

{
    console.log(a); //undefined
    var a = 1;
}
{
    console.log(a);
    let a = 1; //报错
}

既然let“劫持”了所在的块作用域
那么它声明的变量就会 统治所在块作用域
看这个例子

var a = 1;
{
    console.log(a); //报错
    let a = 2;
}

由于let的劫持,并没有打印1
而是报错a未定义


不仅如此,使用let 不能重复声明变量

{
    var a = 1;
    var a = 2;
    console.log(a); //2
}
{
    let a = 1;
    let a = 2;
    console.log(a); //报错:a已声明过
}

使用ES6的let或者说使用块作用域的好处是什么呢
首先变量进一步被限制在“块”中,可以防止变量污染
其次就是防止闭包产生的问题

for(var i = 0; i < 10; i++){
    setTimeout(function(){
        console.log(i);
    }, 200);
}

由于闭包的原因
控制台打印了10个10
为了得到0~9
我们以前的做法通常是加一个立即执行函数

for(var i = 0; i < 10; i++){
    (function(n){
        setTimeout(function(){
            console.log(n);
        }, 200);
    })(i);
}

这样通过增加中间函数作用域可以解决问题
但是let可以更好的解决
只需要把var换成let

for(let i = 0; i < 10; i++){
    setTimeout(function(){
        console.log(i);
    }, 200);
}

这样每次迭代都会进行重新绑定的行为

const

ES6也引入了声明常量的关键字const
const拥有let的全部特点
包括劫持块作用域、无提升行为、不能重复声明等等
但是它用来声明常量
一旦声明就不能更改

const PI = 3.14;
PI = 555; //报错


所以使用const声明必须直接初始化

const PI;
PI = 555; //报错


关于const还有一点要注意

const foo = {
    name: 'a',
    arr: [1,2,3]
};
foo.name = 'b';
foo.arr.push(4);
console.log(JSON.stringify(foo));

引用值之所以可以改变
是因为我们在内存上拿到的是引用值的地址
和我们C/C++中的指针是一样的
我们修改引用值不该变它的地址
所以const并不能限制我们修改引用值

总结

  • let、const用于声明块级作用域变量
  • let、const没有提升行为
  • let、const统治所在块作用域
  • let、const不能重复声明
  • let解决闭包产生的问题
  • const用于声明常量一旦声明不能更改
  • const必须直接初始化
  • const不能限制修改引用值

==主页传送门==

你可能感兴趣的:(Web前端,JavaScript-ES6)