2011-09-30 69 views
2

將某些JavaScript轉換爲CoffeeScript時遇到了問題。基本問題是,我從使用$ .each去了CoffeeScript的解釋,現在我有一個問題,在關閉中捕獲最後一個理解值。讓我們開始與原來的JavaScript:Coffeescript解析和關閉問題

function bindKeyboardControls(websocket) { 
    var moveKeyMap = { 
     Down: ['down', 's'], 
     Up: ['up', 'w'], 
     Left: ['left', 'a'], 
     Right: ['right', 'd'] 
    }; 

    $.each(moveKeyMap, function (direction, keys) { 
     $.each(keys, function (_, key) { 
      $(document).bind('keydown', key, function() { move(websocket, direction); }); 
     }); 
    }); 
}; 

這是我與CoffeeScript的第一次嘗試:

bindKeyboardControls = (websocket) -> 
    moveKeyMap = 
     Down: ['down', 's'] 
     Up: ['up', 'w'] 
     Left: ['left', 'a'] 
     Right: ['right', 'd']   
    for direction, keys of moveKeyMap 
     for key in keys 
      $(document).bind('keydown', key, -> move(websocket, direction)) 
    null 

爲什麼不工作的呢?那麼這裏生成的JavaScript:

bindKeyboardControls = function(websocket) { 
    var direction, key, keys, moveKeyMap, _i, _len; 
    moveKeyMap = { 
    Down: ['down', 's'], 
    Up: ['up', 'w'], 
    Left: ['left', 'a'], 
    Right: ['right', 'd'] 
    }; 
    for (direction in moveKeyMap) { 
    keys = moveKeyMap[direction]; 
    for (_i = 0, _len = keys.length; _i < _len; _i++) { 
     key = keys[_i]; 
     $(document).bind('keydown', key, function() { 
     return move(websocket, direction); 
     }); 
    } 
    } 
    return null; 
}; 

您是否看到'direction'變量是如何在函數頂部聲明的?傳遞給document.bind的函數是在該變量上創建一個閉包,所以在函數運行時,方向將始終等於最後一個值('Right')。

這裏是一個固定的版本,有點醜:

bindKeyboardControls = (websocket) -> 
    moveKeyMap = 
     Down: ['down', 's'] 
     Up: ['up', 'w'] 
     Left: ['left', 'a'] 
     Right: ['right', 'd']   
    for direction, keys of moveKeyMap 
     for key in keys        
      ((d) -> $(document).bind('keydown', key, -> move(websocket, d)))(direction) 
    null   

我也只是回到使用$。每。所以我確實有一些解決方案,但是有更好的解決方案嗎?

回答

5

是:

for direction, keys of moveKeyMap 
    for key in keys 
    do (direction, key) -> $(document).bind('keydown', key, -> move(websocket, d)) 

創建和運行捕獲的directionkey的值,從而使該bind回調可以使用它們的匿名函數。有關詳細信息,請參閱我的PragProg文章A CoffeeScript Intervention

+0

'做'正是我所需要的。謝謝! –