将一些JavaScript转换为CoffeeScript时遇到了问题.基本问题是我从使用$ .each到CoffeeScript理解,现在我遇到了一个问题,即闭包中捕获了理解的最后一个值.让我们从原始JavaScript开始:
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); });
});
});
};
Run Code Online (Sandbox Code Playgroud)
这是我第一次尝试使用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
Run Code Online (Sandbox Code Playgroud)
为什么这不起作用?那么这里是生成的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;
};
Run Code Online (Sandbox Code Playgroud)
你看到在函数的顶部如何声明'direction'变量?传递给document.bind的函数是在该变量上创建一个闭包,因此在函数运行时,direction始终等于最后一个值('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
Run Code Online (Sandbox Code Playgroud)
我也可以回去使用$ .each.所以我确实有一些解决方案,但有更好的解决方案吗?
是:
for direction, keys of moveKeyMap
for key in keys
do (direction, key) -> $(document).bind('keydown', key, -> move(websocket, d))
Run Code Online (Sandbox Code Playgroud)
创建和运行捕获的值的匿名函数direction
和key
,这样的bind
回调可以使用它们.有关详细信息,请参阅我的PragProg文章A CoffeeScript干预.
归档时间: |
|
查看次数: |
503 次 |
最近记录: |