使用jQuery对象表示法的变量闭包

时间:2012-10-26 15:14:47

标签: javascript jquery loops scope closures

我有以下内容:

 for (var i = 0; i <= 10; i += 1) {

    var $page_button = $('<a>', {
        html : i,
        click : function () {

            var index = i;
            console.log(index);
            return false;
        }
    });

    $page_button.appendTo($wrapper);
}

我认为var index将为循环的每次迭代单独定义,因为它包含在一个函数中。在这种情况下,打印的索引值始终为10.

链接文本是i的正确值,因为它被写入DOM,然后是不可变的。

为什么会这样,我应该改变什么来解决我的问题?

我知道这与许多其他问题相似,但使用此表示法的行为导致了不同的结果。我正在使用jQuery 1.7.2(不幸的是,不能使用任何新版本。)

4 个答案:

答案 0 :(得分:4)

您需要将其括在闭包中以解决问题..

var $page_button = $('<a>', {
        html : i,
        click : (function (num) {
           return function(){
               var index = num;
               console.log(index);
               return false;
            }
        })(i)
    });

答案 1 :(得分:2)

i的引用将作为匿名函数的一部分关闭。注意:不是它的,而是对i本身的引用。运行该函数时,将评估该值。因为函数在循环结束后运行,所以该值始终是i的最后一个值。要仅传递,您可以执行以下操作:

    click : (function (index) {
        return function () {
            console.log(index);
            return false;
        };
    })(i)

您创建一个您立即执行的匿名函数,它将一个值作为参数并返回您的实际函数。

答案 2 :(得分:0)

每个处理程序共享相同的i变量。每个人都需要自己的变量范围才能引用唯一索引。

 for (var i = 0; i <= 10; i += 1) {
    var $page_button = $('<a>', {
        html : i,
        click : makeHandler(i)  // invoke makeHandler, which returns a function
    });
    $page_button.appendTo($wrapper);
}

function makeHandler(index) {
    return function () {
                console.log(index);
                return false;
           };
}

这里我创建了一个接受索引参数的makeHandler函数,并返回一个用作处理程序的函数。

因为函数调用设置了一个新的变量作用域,并且因为函数是在makeHandler内创建并返回的,所以返回的每个处理程序都将引用它自己的作用域索引号。

答案 3 :(得分:0)

变量index是为函数的每次执行单独定义的,但是您复制函数内变量i的值,因此您将使用i的值作为它是在函数运行时,而不是在创建函数时。

您需要一个在循环内执行的函数来捕获变量的值:

for (var i = 0; i <= 10; i += 1) {

  (function(){
    var index = i;

    var $page_button = $('<a>', {
      html : i,
      click : function () {
        console.log(index);
        return false;
      }
    });

  })();

  $page_button.appendTo($wrapper);
}