【问题标题】:Looping and closure循环和关闭
【发布时间】:2012-04-07 11:13:54
【问题描述】:

我有一些代码生成一堆button 元素,并通过一些DOM 函数将它们附加到body 中的div。它动态地将一堆匿名函数(事件处理程序)设置为每个buttononclick事件

这是通过从0 迭代到20 来执行的。

问题是,我想在事件处理程序中使用循环计数器i——但是,它在循环中的迭代中的值不是i 达到的最终值。起初,我认为我可以通过关闭来做到这一点,但后来我意识到它并没有像我最初想象的那样执行。 i 每次迭代都在不断变化,所有其他匿名函数(通过闭包?)必须看到相同的 i,因为它的范围内的 i 都指向相同的值。因为当您触发onclick 时它们都报告相同的值。

所以我想,我该如何解决这个问题?我尝试将i 设置为另一个变量等等,但所有结果都相同,因为该新变量的值在每次迭代时都会像i 一样更新。我想我在这里遗漏了一些简单的东西。

<!DOCTYPE html>
<html>
<head>
    <title>loop closure test</title>

<script language="javascript" type="text/javascript">
window.onload = function() {

    var div = document.getElementById("myDiv");

    for( var i = 0; i <= 20; i++ ) {
        var b = document.createElement("button");
        b.setAttribute("type","button");
        b.appendChild(document.createTextNode("Button" + i.toString()));
        b.onclick = function(event) {
            var date = new Date( 2012, 3, i );
            alert( date.getMonth() + "/" + date.getDate() + "/" + date.getFullYear() );
        }       
        div.appendChild(document.createElement("br"));
        div.appendChild(b);
    }       
}
</script>

</head>

<body>
<div id="myDiv"></div>
</body>

</html>

我想了更多,下面的示例答案。基本上我需要将i 困在另一个闭包中。我决定走这条路:

<!DOCTYPE html>
<html>
<head>
    <title>loop closure test</title>

<script language="javascript" type="text/javascript">
window.onload = function() {

    var div = document.getElementById("myDiv");

    for( var i = 0; i <= 20; i++ ) {        
        div.appendChild( (function() {
            var day = i;
            var b = document.createElement("button");
            b.setAttribute("type","button");
            b.appendChild(document.createTextNode("Button" + i.toString()));
            b.onclick = function(event) {
                var date = new Date( 2012, 3, day );
                alert( date.getMonth() + "/" + date.getDate() + "/" + date.getFullYear() );
            }


            return b;
        }()));

        div.appendChild(document.createElement("br"));

    }

}
</script>

</head>

<body>
<div id="myDiv"></div>
</body>

</html>

【问题讨论】:

  • 是的,它可以在每个循环中使用闭包。
  • 要知道的关键是 JavaScript 局部变量的作用域是函数级别。因此,如果你想给每个处理程序自己的“i”,你需要在 another 函数中实例化处理程序函数。关于这个问题有很多很多 StackOverflow 问题。
  • @Pointy 这根本不是 jQuery,你链接的问题对我来说完全陌生。
  • 不管你是否使用jQuery,这都是同一个问题;毕竟,jQuery 只是 JavaScript。

标签: javascript loops dom closures dom-events


【解决方案1】:

尝试使用这样的闭包:

var div = document.getElementById("myDiv");

for( var i = 0; i <= 20; i++ ) {
    var b = document.createElement("button");
    b.setAttribute("type","button");
    b.appendChild(document.createTextNode("Button" + i.toString()));
    b.onclick = function(pos) {
        return function(event) {
                var date = new Date( 2012, 3, pos );
                alert( date.getMonth() + "/" + date.getDate() + "/" + date.getFullYear() );
        }
    }(i);      
    div.appendChild(document.createElement("br"));
    div.appendChild(b);
}   ​

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多