繁体   English   中英

在包含循环变量的循环中定义匿名函数?

[英]Defining anonymous functions in a loop including the looping variable?

我知道这段代码不起作用,我也知道原因。 但是,我不知道如何解决它:

JavaScript的:

var $ = function(id) { return document.getElementById(id); };
document.addEventListener('DOMContentLoaded', function()
{
    for(var i = 1; i <= 3; i++)
    {
        $('a' + i).addEventListener('click', function()
        {
            console.log(i);
        });
    }
});

HTML:

<a href="#" id="a1">1</a>
<a href="#" id="a2">2</a>
<a href="#" id="a3">3</a>

我希望它打印您点击的链接号,而不仅仅是“4”。 我宁愿避免使用节点的属性(id或内容),而是修复循环。

将循环块包装在自己的匿名函数中:

document.addEventListener('DOMContentLoaded', function()
{
        for(var i = 1; i <= 3; i++)
        {
            (function(i) {
                $('a' + i).addEventListener('click', function() {
                    console.log(i);
                })
            })(i);
        }
}

这将创建一个新的i实例,它在每次调用/迭代时都是内部函数的本地实例。 如果没有此本地副本,则传递给addEventListener每个函数(在每次迭代时)将关闭对同一变量的引用,该变量的值在执行任何回调时等于4

问题是内部函数正在创建一个关闭i 从本质上讲,这意味着函数不仅仅是在设置处理程序时记住i的值,而是变量i本身; 它正在为i提供实时参考。

你必须通过将i传递给函数来打破闭包,因为这将导致i副本被创建。

执行此操作的常用方法是使用立即执行的匿名函数。

        for(var i = 1; i <= 3; i++)
        {
            $('a' + i).addEventListener('click', (function(localI)
            {
                return function() { console.log(localI); };
            })(i);
        }

既然你已经在使用jQuery,我会提到jQuery提供了一个数据函数,可以用来简化这样的代码:

        for(var i = 1; i <= 3; i++)
        {
            $('a' + i).data("i", i).click(function()
            {
                console.log($(this).data("i"));
            });
        }

在这里,而不是通过传递破封i一个匿名函数时,你通过传递打破它i到jQuery的data功能。

闭包捕获对变量的引用,而不是副本,这就是为什么它们都会导致'i'的最后一个值。

如果要捕获副本,则需要将其包装在另一个函数中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM