收集下经典面试题for循环
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>for循环经典面试题</title>
</head>
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<script>
var btn = document.querySelectorAll("button")
for(var i = 0; i < btn.length; i ++) {
btn[i].onclick = function() {
alert(i)
}
}
</script>
</body>
</html>
问:
1.为什么点击按钮弹出的都是3。
2.有哪些解决方法。
答:
1.首先事件绑定是异步编程,当触发点击行为,绑定的方法执行的时候,外层循环已经执行完;其次方法执行产生的私有作用域,用到变量i,私有作用域里不存在i,会根据原型链查找机制向上查询,找到的是已经是循环完毕赋值为3的全局变量i
2.
解决方法一:添加自定义属性
<script>
var btn = document.querySelectorAll("button")
for(var i = 0; i < btn.length; i ++) {
// 直接添加自定义属性
// btn[i].index = i
btn[i].onclick = function() {
alert(this.index)
}
// 使用setAttribute添加自定义属性i(会显示在元素上)
// btn[i].setAttribute("index", i)
// btn[i].onclick = function() {
// alert(this.getAttribute("index"))
// }
}
</script>
解决方法二:闭包
<script>
//方式一
var btn = document.querySelectorAll("button")
for(vari = 0; i < btn.length; i ++) {
btn[i].onclick = (function (n) {
return function() {
alert(n)
}
})(i)
}
//方式二
var btn = document.querySelectorAll("button")
for(var i = 0; i < btn.length; i ++) {
function aa (n) {
return function() {
alert(n)
}
}
btn[i].onclick = aa(i)
}
</script>
解决方法三:es6 let
<script>
var btn = document.querySelectorAll("button")
for(let i = 0; i < btn.length; i ++) {
btn[i].onclick = function() {
alert(i)
}
}
</script>