在一个循环中,我附加了一个警告循环索引计数的标记。为什么它始终警告循环的最后一个索引?

时间:2013-08-16 03:18:28

标签: javascript jquery coffeescript

为方便起见,here's an interactive jsfiddle version of my code.以下是有问题的代码:

for i in [1, 2, 3, 4, 5, 6, 7, 8]
  console.log "cell #{i} was created!"
  cell = $('<div class="inventory-cell"></div>').mousedown (event) ->
    alert "#{i} was clicked!"
  $("#inventory-grid").append(cell)

这是html:

<div id="inventory-dialog" class="dialog">    
    <div id="inventory-grid"></div>    
</div>

这是它应该如何工作的。这将在循环中生成一堆单元格。如果我点击第一个我希望它提醒的,“点击了1!”当我点击最后一个时,我想要它说,“8被点击了!”但出于某种原因,我点击的每个人都说,“8被点击”。为什么会这样?

5 个答案:

答案 0 :(得分:4)

所有回调都引用其身体中的相同i变量,当调用任何回调时,该变量的值为8

您需要为每个特定回调创建一个本地变量,该回调在创建回调时保存i

(function(j) {
    var cell = $('<div class="inventory-cell"></div>').mousedown(function(event) {
        alert("#{j} was clicked!");
    });

    $("#inventory-grid").append(cell);
})(i);

功能相同的CoffeeScript将是:

do (i) ->
  cell = $('<div class="inventory-cell"></div>').mousedown (event) ->
    alert "#{i} was clicked!"

  $("#inventory-grid").append(cell)

唯一的区别是do会影响i而不是创建新变量,但结果是相同的。

确切的翻译将是:

do (j = i) ->
  cell = $('<div class="inventory-cell"></div>').mousedown (event) ->
    alert "#{j} was clicked!"

  $("#inventory-grid").append(cell)

答案 1 :(得分:2)

for i in [1, 2, 3, 4, 5, 6, 7, 8]
    do (i) ->
        console.log "cell #{i} was created!"
        cell = $('<div class="inventory-cell"></div>').mousedown (event) ->
            alert "#{i} was clicked!"
        $("#inventory-grid").append(cell)

Fiddle.

答案 2 :(得分:1)

你已经在使用jQuery了,因为 for-in循环不应该在数组上使用(cofeeScript很糟糕,而且明显重命名原生的javascript东西),你可以避免{的封闭问题{1}},如下:

$.each

FIDDLE

答案 3 :(得分:1)

这两个Coffeescript迭代产生相同的Javascript函数。他们只是以不同的方式迭代它。一个使用for (var i=0 ...),另一个使用$.each()

for i in [1..8]
  do (i) ->
    console.log "cell #{i} was created!"
    cell = $('<div class="inventory-cell"></div>').mousedown (event) ->
      alert "#{i} was clicked!"
    $("#inventory-grid").append(cell)
    return

$.each([1..8], (_,i)->
    console.log "cell #{i} was created!"
    cell = $('<div class="inventory-cell"></div>').mousedown (event) ->
      alert "#{i} was clicked!"
    $("#inventory-grid").append(cell)
    return
    )

也可以使用Native Javascript数组迭代:

[1..8].forEach (i)->

其他Javascript迭代方法:

for (i in [1,2,3..]) {}
如果没有注意本地化i定义中使用的cell

会遇到与原始Coffeescript相同的问题。

答案 4 :(得分:0)

不知道coffeescript ......并且不知道为什么(function(){...})();在fsfiddle中出错..

for(var i=1; i<9;i++){
console.log("cell "+ i + "was created!")
~function(i){
    var cell = $('<div class="inventory-cell"></div>').mousedown(function(){
    alert(i+" was clicked!")
    });
  $("#inventory-grid").append(cell)
}(i);
}