如何在JavaScript匿名函数的声明时使用变量的值?

3
这是一个非常基础的问题,但是...
我有一些像这样的代码:
var arr = Array('blah.jpg','ha.jpg');
for (var i=0; i<array.length; i++)
{
    $('div#blah' + i).click(function() {
           $('img').attr('src', arr[i]); });
}

当点击具有id="blah0"的div时,应该将所有图像绑定到'blah.jpg'。同样,点击具有id ="blah1"的div应该将所有图像更改为'ha.jpg'

然而,匿名函数无法正常工作,因为它将在执行时使用'i'的值,即2。这意味着单击任何一个div都将尝试将所有图像设置为arr [2] - 一个不存在的元素(有趣的是,在我的机器上没有引发JS错误,但这是另一件事......)。

我如何使匿名函数在声明时使用'i'的值?

作为一个更简单的例子:

for (var i=0; i<10; i++)
{
    $('div#blah'+i).click(function() {
       alert(i)); });
}

当我点击'blah0'时,应该显示'0',点击'blah1'时应该显示'1'等。然而,默认情况下,无论我点击哪个'blah',它都会显示'10'。
4个回答

5
在创建一个新的点击处理程序的函数内声明一个新变量,该变量将获取i的当前值作为参数:
function makeClickHandler(arr, local_i) {
    return function() {
        $('img').attr('src', arr[local_i]);
    };
}

var arr = Array('blah.jpg','ha.jpg');
for (var i=0; i<array.length; i++)
{
    $('div#blah' + i).click(makeClickHandler(arr, i));
}

每个函数实例都有自己的local_i副本,每次都不会改变。

4
在这种情况下,您应该使用闭包:
for (var i=0; i<10; i++)
{
    (function(j){
        $('div#blah'+j).click(function() { alert(j)); });
    })(i);        
}

(function(){ /* code */ })() 表示自执行函数,这意味着它会立即在循环中使用和评估 i 的值,而不是在点击时间。


0

在循环内部再加一个变量,使用它在闭包中后将其递增。


var j = 0;
for (var i=0; i<array.length; i++)
{
    $('div#blah' + j).click(function() {
           $('img').attr('src', arr[i]); });
j++; }

问题不在于绑定(即 'div#blah'+j),而在于数组访问(即 arr[i])。在您使用的方法中,根本没有任何区别 - 单击仍将调用使用i值(例如array.length)而不是在i制作函数时的i值来调用arr的“i”元素。 - Matt Mitchell
虽然我不太理解闭包,但你可以让点击调用一个单一的函数并检查Event.Src(它将给出div1、div2或div3),从中提取id,并根据此设置图像源。 - shahkalpesh
你的第二个选项应该可以工作。不确定新的function(){}。 - Matt Mitchell

0

我目前有这个答案,但有一点hack:

var arr = Array('blah.jpg','ha.jpg');
for (var i=0; i<array.length; i++)
{
    eval("$('div#blah' + i).click(function() { $('img').attr('src', arr[" + i + "]); })");
}

另外:

for (var i=0; i<10; i++)
{
    eval("$('div#blah'+i).click(function() { alert(" + i + ")); });");
}

如果单行评估太长,也可以使用多行hack,例如这里http://forums.whirlpool.net.au/forum-replies-archive.cfm/487804.html。 - Matt Mitchell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接