ES6块级作用域

ES5中,没有块级作用域,所以会出现以下情况:

var callbacks = []; for(var i=0; i<=2; i++){ callbacks[i] = function(){ return i * 2; } }console.table([ callbacks[0](), callbacks[1](), callbacks[2](), ])

这段代码的结果是输出3个6。
首先var i=0这一句话,将i做了一个变量提升,i是一个跟callbacks平级的变量;
然后进行for循环,for 循环结束时,i的值已经被更新成为了3;
由于function(){return i*2}不是立即被调用的,而是循环结束后,也就是i等于3的时候才调用的,它执行的时候会去找它上一级作用域中i的值,发现i等于3,于是进行计算并输出,所以callbacks[0](),callbacks[1](),callbacks[2]()的结果全部都是6。
ES6中我们可以用let来声明变量,将变量的作用域限定为块级作用域,不存在变量提升:
const callbacks = []; for(let i=0; i<=2; i++){ callbacks[i] = function(){ return i * 2; } }console.table([ callbacks[0](), callbacks[1](), callbacks[2](), ])

结果为0,2,4。
let声明的变量为块作用域,作用于当前块;每次循环都会把值保留下来供后面的闭包使用。
这段for循环等价于:
for (let i = 0; i < 10; i++) { a[i] = (function(i) { return function(){ console.log(i); } })(i); }

在ES6中只需一个花括号就可以指定块作用域。
{ function foo(){ return 1; } console.log(foo() === 1); { function foo(){ return 2; } console.log(foo() === 2); }console.log(foo() === 1); }

【ES6块级作用域】结果是打印3个true。
可见两个作用域没有相互影响,一对花括号就已经把作用域隔离。

    推荐阅读