MooTools / JavaScript变量范围

时间:2010-06-13 02:20:20

标签: javascript loops mootools closures scope

我正在尝试使每个数字显示为可点击。 “1”应该alert() 80,“2”应该产生60等等。

但是,当调用alert(adjust)时,它只显示0,而不是正确的数字。但是,如果注释掉alert(adjust)已取消注释,则会在页面加载时生成正确的数字,但不会在点击时生成。

我想知道为什么addEvents中的代码无法访问先前定义的变量adjust

<html>
<head>
<script type="text/javascript" charset="utf-8" src="mootools.js"></script>
<script type="text/javascript" charset="utf-8">
    window.addEvent('domready', function() {

            var id_numbers = [1,2,3,4,5];

            for(var i = 0; i<id_numbers.length; i++) {
                var adjust = (20 * (5 - id_numbers[i]));
                // alert(adjust);
                $('i_' + id_numbers[i]).addEvents({
                    'click': function() {
                        alert(adjust);
                    }
                });
            }

    });
</script>
</head>
<body>

<div id="i_1">1</div>
<div id="i_2">2</div>
<div id="i_3">3</div>
<div id="i_4">4</div>
<div id="i_5">5</div>

</body>
</html>

感谢。

1 个答案:

答案 0 :(得分:3)

您在for循环中拥有a very common closure problem

封闭在闭包中的变量共享相同的单一环境,因此在调用click回调时,for循环将运行,adjust变量将留下指向它所分配的最后一个值。

您可以使用函数工厂解决更多关闭问题:

function makeClickHandler(adjust) {  
   return function() {  
      alert(adjust);
   };  
}

// ...

for(var i = 0; i<id_numbers.length; i++) {
   var adjust = (20 * (5 - id_numbers[i]));

   $('i_' + id_numbers[i]).addEvents({
      'click': makeClickHandler(adjust)
   });
}

如果你不熟悉闭包的工作方式,这可能是一个非常棘手的话题。您可以查看以下Mozilla文章以获得简要介绍: