【JS】深入理解ES6——块级作用域绑定
想了很久还是决定一边看书一边把所记多得用博客的形式记录下来。毕竟好记性不如烂笔头嘛,而且,ES6这么多的内容很适合记博客啊,哈哈~~ 可以产出很多篇不说,还可以顺便练练文笔什么的啦… 额,废话就直接跳过了
ES6的新语法可以让我们更好地控制作用域。这里我们先理解var声明的一些坑,然后从ES6新引入的块级作用域说起,然后到其绑定机制和最佳实践。
var声明及变量提升机制
1 | function getValue(something) { |
我们读着代码,可能会认为只有something为true(存在)时,value才会被声明,但事实上,在预编译
阶段,JavaScritp引擎会将上面的getValue函数修成成下面这样
1 | // 这里是全局作用域 window或global下 |
变量value的声明被提升至顶部。所以在注释处我们都可以在getValue函数内部
访问到value。那ES6引入块级作用域就是来强化对变量声明周期的控制的。
块级声明
块级声明用于声明在指定块的作用域之外无法访问的变量,块级作用域存在于:函数内部和块中(字符
{ }
之前的区域)
let和const
还是以刚才的代码为例:
1 | // 这里是全局作用域 window或global下 |
用let或const进行的声明不再被提升至函数顶部。执行流离开if块后,value、PI被立即销毁,如果something为false,就永不会声明及初始化变量。
二者间的相同点 禁止重声明
在同级的作用域内,若变量用let或const声明过后,再次声明会直接报错
。但如果当前作用域嵌另一个作用域便可在内嵌的作用域中用let或const声明同名变量:
1 | var name = 'fri'; |
临时死区 (Temporal Dead Zone)
JavaScript引擎在扫描代码时发现变量声明,要么将它们提升至作用域顶部(遇到var声明),要么将声明放到TDZ中(遇到let或const声明)
访问TDZ中的变量会触发运行时错误。只有执行过变量声明语句后,变量才会从TDZ中移出,然后才可正常访问。
总结
块级作用域绑定的let和const为JavaScript引入了词法作用域(它们声明的变量不会提升),而且只可以在声明这些变量的代码块中使用。
在for-in和for-of循环中,let和const都会为每次迭代时创建新绑定(从而使循环体内创建的函数可以访问到相应迭代的值,而非最后一次迭代后的值)
注:在for循环中使用const声明可能引发错误,要尽量避免
- 使用块级作用域绑定的最佳实践是:默认使用const,只有在确实需要改变变量时才使用let