2011-09-30 68 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

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