先看下触发闭包的情景,页面上有很多div,点击div输出对应的系列值。
按照以前的思路可能是以下代码:
var p = document.querySelectorAll('div');
for (var i = 0; i < p.length; i++) {
p[i].onclick = function () {
console.log(i);
}
}
按照这代码,问题来了,每次都是一样的值输出来。这就是出现前说的闭包触发,计数器i只在for循环体内有效,在循环体外引用就会报错。那么改下代码呢,完成闭包问题。当然这里不管理冒泡的问题。
var p = document.querySelectorAll('div');
for (var i = 0; i < p.length; i++) {
(function (j) {
p[j].onclick = function () {
console.log(j);
}
}) (i);
}
在ES6中,引用了块级,一个{}是一个块,上下不影响。所以只需要小小改动下for中的变量定义,var 改为 let。
{
let p = document.querySelectorAll('div');
for (let i = 0; i < p.length; i++) {
p[i].onclick = function () {
console.log(i);
}
}
}
ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。所以for循环的计数器,就很合适使用let命令。上述使用let,声明的变量仅在块级作用域内有效。
转载请注明:TUTERM.COM » 旧js与es6处理闭包问题区别及优势
