1

为方便起见,这是我的代码的交互式 jsfiddle 版本。 这是有问题的代码:

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 被点击了”。为什么会这样?

4

5 回答 5

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)
于 2013-08-16T03:27:28.690 回答
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)

小提琴。

于 2013-08-16T03:28:45.213 回答
1

您已经在使用 jQuery,并且由于不应该在数组上使用 for-in 循环(cofeeScript 很烂,而且显然重命名了本机 javascript 内容),您可以避免使用 的闭包问题$.each,如下所示:

$.each([1, 2, 3, 4, 5, 6, 7, 8], function(_,i) {
    var cell = $('<div />', {
        'class': 'inventory-cell',
         on    : {
                  click: function() { alert('#{'+i+'} was clicked!'); }
                 }
    });
    $("#inventory-grid").append(cell);
});

小提琴

于 2013-08-16T03:34:07.813 回答
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
    )

也可以使用原生 Javascript 数组迭代:

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

另一种 Javascript 迭代方法:

for (i in [1,2,3..]) {}

i如果它不注意本地化定义中使用的内容,则会与原始 Coffeescript 存在相同的问题cell

于 2013-08-16T05:48:20.767 回答
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);
}
于 2013-08-16T04:05:46.220 回答