在给一串按钮用循环语句绑定事件时,许多初学者可能会犯一个错误
btn = document.getElementByTagName(Button);
for(var i=0;i<9;i++){
btn[i].onclick =function(){
btn[i].className=' ';
consloe.log(i);
}
}
假如有10个按钮。原本想要实现点击每个按钮时,被点击按钮的className节点为空,并且输出被点击的是第几个按钮。
但是无论点击哪一个按钮,输出结果都为:9
并且只有第十个按钮的className节点变空了。
原因:
for语句在执行完后,i变量变成了9.所以每个按钮绑定的事件响应函数中的变量i都变为了9
解决方法:
- 使用立即执行函数使按钮响应函数生成闭包
- 使用let声明变量
第一种方法:
立即执行函数使按钮响应函数生成闭包,不释放原有的作用域链,方法体中的i不因for循环改变。
//第一种用法:
for(var i=0;i<btn.length-1;i++){
btn[i].onclick = (function(n){
return function(){
btn[i].className=' ';
consloe.log(i);
}
}
}(i));
}
//第二种用法:
for(var i=0;i<btn.length-1;i++){
(function(n){
btn[i].onclick = function(){
btn[i].className=' ';
consloe.log(i);
}
}(i));
}
第二种方法:
let关键字相比于var,作用域方面有所不同:
var的作用域是会提升的,var声明的变量只能是全局的或者是整个函数块的。
let则允许声明一个作用域被限制在块级中的变量、语句或者表达式。
可以使用let声明变量i,使得for循环语句执行时,方法体中的i变量不会改变。