webstermobile
Fork me on GitHub
个人博客

关于js批量绑定事件的问题

<body>  
<ul id="list">  
<li>1</li>  
<li>2</li>  
<li>3</li>  
<li>4</li>  
<li>5</li>  
</ul>  
<script>  
var list_obj = document.getElementsByTagName('li');  
for (var i = 0; i <= list_obj.length; i++) {        
  list_obj[i].onclick = function() {      
    alert(i);      
  }  
}  
</script>  
</body> 

  for循环绑定完事件最后执行的时候都是最后一个事件相同,点击的时候弹出的不是0 1 2 3 4,而是5,这是为什么呢 如何解决

原因:当调用onclick事件的时候,会向上找到i对象的值。这个时候,由于已经循环完毕,所以i的值是5

解决方法:

1、闭包

1 for (var i = 0; i <= list_obj.length; i++) {
2   list_obj[i].onclick = (function(i){
3     return function() {  alert(i); }
4   })(i);  
5 } 

2、ES6

for (let i = 0; i <= list_obj.length; i++) {        
  list_obj[i].onclick = function() {      
    alert(i);      
  }  
}  

  关于Let做下说明

下面的代码如果使用var,最后输出的是10

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

  上面代码中,变量ivar声明的,在全局范围内都有效。所以每一次循环,新的i值都会覆盖旧值,导致最后输出的是最后一轮的i的值。

如果使用let,声明的变量仅在块级作用域内有效,最后输出的是6。

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

  上面代码中,变量ilet声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。你可能会问,如果每一轮循环的变量i都是重新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。

posted @ 2017-02-21 11:43  wpindesign  阅读(138)  评论(0编辑  收藏