这个问题不好描述,哪位大佬进来看一下?

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>test</title>
  </head>
  <body>
    <button>1111</button>
    <button>2222</button>
    <button>3333</button>
  </body>
  <script>
    for(var i=0;i<3;i++){
      document.getElementsByTagName("button")[i].onclick=function(){
        alert(i);
      }
    }
  </script>
</html>

为什么点击每个按钮都会弹出3??

因为你需要在事件内使用事件外的循环变量i。
当事件触发时,那个循环早就结束了,那时的i的值已经是循环最大值加1了。
所以需要用一些方式保存住当前循环的i的值。

#### 方案一:用闭包保存住当前循环的i的值
for (var i = 0; i < arr.length; i++) {
    (function(i){
        arr[i].onclick = function () {
            alert(i);
        }
    })(i);
}

#### 方案二:用let块作用域变量
for (var i = 0; i < arr.length; i++) {
    let k = i;
    arr[i].onclick = function () {
        alert(k);
    }
}
ps:IE11中在for语的()内声明的let是整个循环体中共用的,只有在{}内声明的let才是每次循环都独立的。
非ie的浏览器中可以在中在for语的()内声明let
for (let i = 0; i < arr.length; i++)

方案三:为事件元素设置一个index属性,在事件函数内通过this获取当前对象并访问index属性。
for (var i = 0; i < arr.length; i++) {
    arr[i].index = i;
    arr[i].onclick = function () {
        alert(this.index);
    }
}
 

var   改成let 应该可以拿

我怎么感觉你点一下按钮,他for循环完了之后永远都是alert3。哈哈,猜测而已