首页 > 创建了5个按钮,但是每个按钮点击后都会弹出5,不知道为什么??

创建了5个按钮,但是每个按钮点击后都会弹出5,不知道为什么??

for(var i =0;i<5;i++)
{
button = document.createElement("button");
button.innerHTML = "Button" + i;
document.body.appendChild(button);
button.addEventListener("click",function(e){alert(i);},false);
}
结果是创建了5个按钮,但是每个按钮点击后都会弹出5,不知道为什么??

我本以为这样也可以,希望点击的时候回触发函数x,但是每次创建一个按钮就会自动触发函数x???
for(var i =0;i<5;i++)
{function x(e){alert(e)}
button = document.createElement("button");
button.innerHTML = "Button" + i;
document.body.appendChild(button);
button.addEventListener("click",x(i),false);
}


最后i是5啊, 你想想


循环执行完后,i的值最终被赋值为5,执行click事件的回调函数时,才会去作用域中查找i变量的值,自然就alert出5,因为ES5没有块级作用域,所以只能利用函数作用域,一个闭包的匿名函数自执行即可,分别创建单独的变量。

for(var i =0;i<5;i++)
{
button = document.createElement("button");
button.innerHTML = "Button" + i;
document.body.appendChild(button);
(function(i){button.addEventListener("click",function(e){alert(i);},false);})(i)
}

i 不在 function (e) {} 这个作用域里,向上一直找到for 下面那级作用域,而这个i一直在++,for循环执行完毕i就是5


又是闭包的问题,总是见到人们问这个问题。自行百度就会有各种各样的答案。

ES 5.1 只有函数作用域,不是说有个{} 就会创建一个新的作用。而是只有函数定义中的{}才能形成一级新的作用域。
for 的 i 定义在全局,因此全局只定义了一个变量i。
回调的那个匿名函数会形成一级新的作用域,但是其中没有定义变量 i。 因此,匿名函数中访问的 i 是全局的 i。而全局变量中只定义了一个 i,怎么可能不同的时候分别等于1,2,3,4,5

for(var i =0;i<5;i++)
{
button = document.createElement("button");
button.innerHTML = "Button" + i;
document.body.appendChild(button);
(function(){
    var j = i;
    button.addEventListener("click",function(e){alert(j)},false);
})()
}

上述代码,在我的匿名函数执行的时候,会创建一个新的作用域,循环 5 次,所以会形成5 个不同的作用域中的j。每次循环创建一个作用域,而给 j 赋值的时候 i,i分别等于1,2,3,4,5,所以5个作用域中的j分别等于1,2,3,4,5。回调函数中的匿名函数也是分别在这5个不同作用域中,因此他们分别对应各自作用域中的j,所以可以得到 1,2,3,4,5;

或者 HTML5

for(let i =0;i<5;i++)
{
button = document.createElement("button");
button.innerHTML = "Button" + i;
document.body.appendChild(button);
button.addEventListener("click",function(e){alert(i);},false);
}

let 的语法:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

【热门文章】
【热门文章】