ES6中对声明变量增加了两个关键字let和const,相比于之前的var,后者具有块级作用域而且不具有可重复声明和变量提升的特性,在如下for循环的例子中是否变量提升将会导致截然不同的运行结果
由于var声明的变量存在变量提升,每一次循环,变量i的值都会发生改变,而循环内被赋给数组arr的函数内部的return i里面的i指向的就是全局的i。for循环中var声明的变量i会被提到for循环外上面但不会赋值,在for循环内才开始给"i"赋值,当在循环外调用这10个函数中的任意一个,都会返回10,因为当函数被调用需要返回i时,发现函数内部并没有声明变量i于是开始向上寻找找到了全局定义的i(变量提升),并且循环已经执行结束,i的值为10。简而言之:循环内被赋给数组a的函数内部的return i里面的i指向的就是全局的i
此时可以将函数表达式声明的函数转变为立即函数将能输出5,因为每一轮循环中,该函数都会立即执行并返回给相应数组元素一个值,此时的值就是当前循环变量i的值。
使用let来声明for循环的i ,由于let声明的变量具有块级作用域,即当前的i只在本轮循环有效,所以每一次循环就需要向事件队列中添加一个打印i的事件,每一个同步事件队列中的函数对应自己的i值