学习js闭包时遇到的循环事件注册问题

在学习闭包的时候,举了那个常用的例子:
html

<ul>
        <li>123</li>
        <li>456</li>
        <li>789</li>
        <li>010</li>
    </ul>

js01

    window.onload = function () {
            var aLi = document.getElementsByTagName('li');
            for (var i = 0; i < aLi.length; i++) {
                aLi[i].onclick = function () {
                    alert(i);
                };
            }
        }

一般会拿上面那个举例子,然后点击li是,4,4,4,4
js02

      for (i = 0; i < aLi.length; i++) {
                !function (i) {
                    aLi[i].onclick = function () {
                        console.log('a', i)
                    };
                }(i)
            }

上面这个方案,立即执行,闭包,解决问题
js03

            for (let i = 0; i < aLi.length; i++) {
                    aLi[i].onclick = function () {
                        console.log('a', i)
                    };
            }

我发现js03这段也是work的,可以打印出0,1,2,3
无法理解js03为什么又可以了?

阅读 2.1k
2 个回答

let、const 是ES6的变量声明,在作用域内是不会变量提升,可以简单理解为:在循环体内相当于多次定义并执行。

aLi[0].onclick = function () {
    console.log('a', 0)
};
aLi[1].onclick = function () {
    console.log('a', 1)
};
...