先看下触发闭包的情景,页面上有很多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处理闭包问题区别及优势