JS变量范围误解

时间:2010-04-22 07:55:23

标签: javascript

我有一点问题: slideHelpers.total = 4

for (i=1;i <= slideHelpers.total; i++) {
    $('<a href="#">' + i + '</a>').bind('click', function(){ alert('go to the ' + i + ' slide')}).appendTo('.slideaccess')
}

警报给出了什么是逻辑,因为当函数点击触发时我实际上是5.但是我希望在我的<a>标签中使用相同的i。处理这个问题的最佳方法是什么?

我可以将i放在<a>标签的data()中,但我相信有一种更简单的方法。

5 个答案:

答案 0 :(得分:2)

for (i=1;i <= slideHelpers.total; i++) {
    $('<a href="#">' + i + '</a>').bind('click',
        (function(i){
            // Capture i in closure
            return function(){
                alert('go to the ' + i + ' slide')
            };
        })(i)
    ).appendTo('.slideaccess')
}

优化

var ary = [], i = 0, n = slideHelpers.total,
    open = '<a class="index" href="#">',
    close = '</a>';

// Fill array with numbers: 1,2,3,4,5...
while (++i < n) ary[i] = i + 1;

$('.slideaccess').append(
    open + ary.join(close + open) + close
).delegate('a.index', 'click', function() {
    var index = $.text(this);
    alert('go to the ' + index  + ' slide');
});

答案 1 :(得分:2)

您可以使用返回功能的附加功能:

for (i=1;i <= slideHelpers.total; i++) {
    $('<a href="#">' + i + '</a>').bind('click',
        (function(i) {
            return function() {
                alert('go to the ' + i + ' slide');
            };
         })(i)
     ).appendTo('.slideaccess');
}

使用此附加功能,i中的内部alert引用该函数的参数i,而不是外部范围的i

答案 2 :(得分:1)

您需要创建一个新范围,否则每个函数都将引用相同的i。在JavaScript中,变量的作用域是函数。

var make_alert_message = function make_alert_message(num) {
    return function () { 
        alert('go to the ' + num + ' slide');
    };
}

for (var i = 1; i <= slideHelpers.total; i++) {
    $('<a href="#">' + i + '</a>').bind(
        'click', make_alert_message(i)
        ).appendTo('.slideaccess')
}

答案 3 :(得分:1)

在您的代码示例中,i基本上是一个全局变量。到alert()代码执行时,i具有for循环的最大值。在JavaScript中修复此问题的标准方法是创建一个新函数,该函数有自己的scope来“保持”变量。以此代码为例,它返回您的事件处理函数:

(function(i) { // using i as an argument here 'scopes' it
   var something = i; // also within this function scope.
   // inside here, both i and something will only ever reference the "local scope"

   return function() {
     alert(i);
   };
})(i); // and here we are calling that function with i = 1,2,3,...

答案 4 :(得分:0)

您可以使用绑定功能的eventData

for (var i = 1; i <= slideHelpers.total; i++) {
    $('<a href="#">' + i + '</a>').bind('click', { index: i }, function(arg) { 
        alert('go to the ' + arg.data.index + ' slide');
    }).appendTo('.slideaccess');
}