为什么这个html / javascript组合打印出来的方式呢?

时间:2011-07-29 16:45:14

标签: javascript jquery javascript-events

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Ovi Maps API Example</title>

  </head>
  <body>
      <button id="butt1" name="butt" type="button">Click Me!</button>
      <button id="butt2" name="butt" type="button">Click Me!</button>
      <button id="butt3" name="butt" type="button">Click Me!</button>
  </body>
   <script src="jquery.js" type="text/javascript" charset="utf-8"></script>
   <script src="foo.js" type="text/javascript" charset="utf-8"></script>
</html>

和...

$(document).ready(function() {
//alert("ready");
var myClickFunctions = new Array();

//add event handlers to all three buttons
for(var i=1;i<=3;i++){

  myClickFunctions[i]=function(){
    var index = i;
    alert(index);
  }

  var buttonID = "#butt";
  var button  = $(buttonID + i);    
  button.click(myClickFunctions[i]);
}

});

每个按钮都会打印4.为什么这是一个很好的方法,让每个按钮打印出创建处理程序的i的值?

4 个答案:

答案 0 :(得分:4)

阅读JavaScript闭包及其工作原理。事实是底部i中的button.click(myClickFunctions[i]);最后会是4。请记住,只有在调用函数时,才会声明var index = i。你需要做的是将函数包装在一个闭包中,如下所示:

  myClickFunctions[i]=(function(i){
    return function(){
      var index = i;
      alert(index);
    }
  })(i)

或者更好,做到这一点:

//put this anywhere
function myClickFunctions(i){
  return function(){
    alert(i);
  }
}

//and at the end:
button.click(myClickFunctions(i));

myClickFunctions函数将获取i的当前值,并返回已设置该值的函数。这是正确的方法。

答案 1 :(得分:2)

您设置为myClickFunctions[i]的匿名函数正在围绕i创建一个闭包。闭包关闭变量本身,而不是闭包时的值。因此,当函数实际运行时,i为4,因此您将始终获得4.

一个简单的解决方法是调用一个返回函数的函数,并捕获i的当前值。

myClickFunctions[i] = (function(curI) {
     return function() {
        var index = curI;
        alert(index);
     };
})(i);

如果这令人困惑,那么我建议您阅读JavaScript中的闭包。一段时间后,它们成为第二天性。

答案 2 :(得分:0)

因为每次函数循环时都会为同一个变量赋值,所以当单击任何按钮时var index为4。

使每个锚标记打印出其索引的快速方法将附加如下内容:

$('a').click(function() {
    var theAnchors = $('a');
    for (i in theAnchors)
        if (theAnchors[i] == this)
            alert(i);
});

我能看到的唯一问题是,我怀疑当被比较的两个DOM元素完全相同时,对象相等性比较只会验证为真,但它们可以。

此外,您在这里尝试完成的最终目标是什么(因为我确信在点击任何锚点时制作一个骚扰用户警报的页面不是您的预期最终目标。)

答案 3 :(得分:0)

循环结束时“i”的值为“4”,因此每次单击按钮时,显示的数字为“4”,因为您正在访问“i”的引用和当您在循环期间没有单击按钮时,函数正在执行。

如果你想得到“i”的数字与按钮id相同,所以我建议这样做。

$(document).ready(function() {
//alert("ready");
var myClickFunctions = new Array();

//add event handlers to all three buttons
for(var i=1;i<=3;i++){

  myClickFunctions[i]=function(){
    var id = $(this).attr('id');
    var index = id.replace('butt', '');
    alert(index);
  }

  var buttonID = "#butt";
  var button  = $(buttonID + i);    
  button.click(myClickFunctions[i]);
}

});