ES6新特性---let与块级作用域、Const

let与块级作用域

在ES2015之前,ES只有两种作用域即函数作用域和全局作用域,在ES2015中新增了一个作用域即块级作用域。
块就是代码中我们用两个{ }包起来的内容。
在此之前,块是没有作用域的,也就是说你在块内定义的变量在外部也可以访问到。如下图:
ES6新特性---let与块级作用域、Const
这点对于今后项目组复杂的开发是非常不利的,并且也是不安全的。
并且这种问题也会出现在嵌套循环计数器中,如下图:
ES6新特性---let与块级作用域、Const
这里外层循环计数器中的i会被内层中的计数器声明所覆盖。并且此时的var时在全局作用域中的。
在将var改成let后就将两个块内的计数器变量分离开来。不会导致重复声明时覆盖上层的变量。
ES6新特性---let与块级作用域、Const
此处真正解决问题的是在内存循环中的let声明,这让内层循环中的计数器与外层彻底分离开来,所以将外层计数器声明改为全局作用域var也能够正常运行。

除此之外,还有一个典型的应用场景,就是我们通过for循环去注册事件的时候。由于不在web环境,这里我们用函数去模拟一下
ES6新特性---let与块级作用域、Const
任意调用elements成员中的的onclick都是3,是因为这里的 i 都是全局作用域里的 i 在循环过后,i 的值已经被累加到了3所以说都是3。
这也是闭包的一个典型的应用场景,建立闭包就可以解决这样一个问题
ES6新特性---let与块级作用域、Const
闭包的作用原理其实也就是借助于函数作用域去摆脱全局作用域所产生的影响。
现在有了块级作用域,所以不用这么麻烦了。只要将计数器的var 改成let即可。
ES6新特性---let与块级作用域、Const
还需要注意一点的是,在for循环中连续声明两个 i 并不会冲突,其实每个for循环中都有两层作用域。
ES6新特性---let与块级作用域、Const
除了let会产生块级作用域之外,let和var还有一个很大的区别,let的声明不会出现提升的情况。
传统的var去声明变量,都会把变量提升到代码最开始的位置。
ES6新特性---let与块级作用域、Const
此时控制台并不会报未定义的错误,而是打印了undefined。这也就说明我们在打印之前 i 这个变量就已经声明了,只是还没有赋值。这就是var的提升。

为了纠正这个问题,所以推出了let关键词,需要先声明再使用。否则会报错。

Const

ES2015中还新增了一个Const关键词,它是一个常量,且声明时必须初始化,它的特点就是在let的基础上多了一个只读的属性,所谓只读就是变量一旦声明之后无法被修改。
注意是无法修改的时指向对象的地址,即可以修改所声明对象的属性值,但是无法改变指向的对象的地址。

到现在为止一共有三个声明变量关键词,分别是var let const,我的建议是尽量不使用var。根据是否可修改来使用let和const