闭包问题
今天要说的是JavaScript的闭包问题,先来看代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <script type="text/javascript"> for (var i = 0; i < json["length"]; i++) { x += "<td>" + json[i]["contents"] + "</td>"; var row = document.createElement('tr'); row.innerHTML = x; var op = document.createElement('button'); op.innerText = "购买"; op.setAttribute('style', 'height: 35px; width: 70px; padding-right: 10px; margin: 0 auto;'); op.addEventListener('click', function () { buyLoan(json[i]); }, false); row.appendChild(op); tbody.appendChild(row); x = ""; }
</script>
|
上边的代码中”json”是获取的数据信息,遍历数据信息,添加购买按钮。
这是一个很典型的闭包问题,因为JavaScript没有块级作用域(for, if, while),var定义的变量会变为全局变量。
这种情况发生之下就是,当代码运行时,每运行一次i都会被覆盖,始终是最后的一个元素。
解决方法
使用let定义变量
从ES6开始,就可以使用let来定义块级作用域的变量了。
1 2 3 4 5 6 7 8 9
| <script type="text/javascript"> 'use strict'
let demo = 0; console.log(demo);
</script>
|
使用立即执行函数解决
立即执行函数最常用的场景就是将var变量的作用域限制在你的函数里,这样可以避免命名冲突和变量变化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <script type="text/javascript">
for (var i = 0; i < json["length"]; i++) { (function (i) { x += "<td>" + json[i]["contents"] + "</td>"; var row = document.createElement('tr'); row.innerHTML = x; var op = document.createElement('button'); op.innerText = "购买"; op.setAttribute('style', 'height: 35px; width: 70px; padding-right: 10px; margin: 0 auto;'); op.addEventListener('click', function () { buyLoan(json[i]); }, false); row.appendChild(op); tbody.appendChild(row); x = ""; }(i)); }
</script>
|
解决来源
StackOverFlow
var与let的区别