在JavaScript中的循环中创建闭包

在JavaScript中的循环中创建闭包,javascript,Javascript,我有这样一个场景: <html> <head> <script type="text/javascript" src="jquery-1.4.4.js"></script> <script type="text/javascript"> var actions = { 'view' : function(){alert("view");}, 'history': function(){alert("history");}

我有这样一个场景:

<html>
<head>
<script type="text/javascript" src="jquery-1.4.4.js"></script>
<script type="text/javascript">
var actions = {
    'view' : function(){alert("view");},
    'history': function(){alert("history");},
    'renewal': function(){alert("renewal");}
}
for(var action in actions){
    $('.' + action).live('click', function(e){
        e.preventDefault();
        if(actions[action])
            actions[action]();
    });
}
</script>
</head>
<body>
    <a class="view" href="#">view</a>
    <a class="history" href="#">history</a>
    <a class="renewal" href="#">renewal</a>
</body>
</html>

我认为已经创建了一个关闭,因为单击链接总是会提醒续订,而我无法修复它。

为什么不尝试在单击事件中使用类名

我不是jQuery专家,但类似这样:

$('.' + action).live('click', function(e)
{
 e.preventDefault();
 if(actions[this.className])
   actions[this.className]();
});

为什么不尝试在单击事件中使用类名呢

我不是jQuery专家,但类似这样:

$('.' + action).live('click', function(e)
{
 e.preventDefault();
 if(actions[this.className])
   actions[this.className]();
});

的确如此。你可以替换

for(var action in actions){
    $('.' + action).live('click', function(e){
        e.preventDefault();
        if(actions[action])
            actions[action]();
    });
}


顺便说一句,问题不在于有一个结束。事实上,如果没有闭包,变量action的值就不会被记住!问题是,循环中的所有函数都引用相同的变量操作,循环结束时会有值更新。

确实如此。你可以替换

for(var action in actions){
    $('.' + action).live('click', function(e){
        e.preventDefault();
        if(actions[action])
            actions[action]();
    });
}


顺便说一句,问题不在于有一个结束。事实上,如果没有闭包,变量action的值就不会被记住!问题是,循环中的所有函数都引用相同的变量操作,循环结束时将有值更新。

有更好的方法可以做到这一点,但要使解决方案正常工作:

for(var action in actions){
    (function(myAction){
        $('.' + myAction).live('click', function(e){
            e.preventDefault();
            if(actions[myAction])
                actions[myAction]();
        });
    })(action);
}

您将发现live不会取消默认操作,您需要使用

有更好的方法来执行此操作,但要使您的解决方案正常工作:

for(var action in actions){
    (function(myAction){
        $('.' + myAction).live('click', function(e){
            e.preventDefault();
            if(actions[myAction])
                actions[myAction]();
        });
    })(action);
}

您将发现live不会取消默认操作,您将希望使用

但实际情况并非如此。相反,事件处理程序函数引用action变量,该变量始终具有值“renewal”,因为这是循环完成后列表中的最后一项。最好的方法是将循环替换为以下内容:

for(var action in actions) {
    $('.' + action).live('click', function(e){
        e.preventDefault();
        var action = $(e.currentTarget).attr('class');
        if(actions[action]) actions[action]();
   });
}

事实并非如此。相反,事件处理程序函数引用action变量,该变量始终具有值“renewal”,因为这是循环完成后列表中的最后一项。最好的方法是将循环替换为以下内容:

for(var action in actions) {
    $('.' + action).live('click', function(e){
        e.preventDefault();
        var action = $(e.currentTarget).attr('class');
        if(actions[action]) actions[action]();
   });
}

这个基本问题必须占所有JavaScript问题的10%:-你是说闭包是某种错误吗?因为它不是。这个基本问题的可能重复必须占所有JavaScript问题的10%:-你是说闭包是某种错误吗?因为它不可能重复