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

时间:2008-11-21 03:48:41

标签: javascript jquery closures

这是一个非常基本的问题,但是......

我有一些像这样的代码

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]); });
}

这应该将div与id="blah0"绑定,以便在点击时将所有图片更改为'blah.jpg'。 同样,点击带有id ="blah1"的div会将所有图片更改为'ha.jpg'

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

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

作为一个更简单的例子:

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

单击'blah0'时显示'0',单击'blah1'等时显示'1'。

然而,默认情况下,无论点击哪个',我都会显示'10'。

4 个答案:

答案 0 :(得分: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副本,每次都不会更改。

答案 1 :(得分:4)

在这种特殊情况下,你应该使用一个闭包:

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

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

答案 2 :(得分:0)

在循环中再增加一个变量,并在闭包中使用它后增加它。


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

    j++;
}

答案 3 :(得分:0)

到目前为止我有这个答案,但有点像黑客:

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 + ")); });");
}