簡體   English   中英

Coffeescript理解和閉包問題

[英]Issue with Coffeescript comprehensions and closures

將一些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); });
        });
    });
};

這是我第一次嘗試使用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的函數正在該變量上創建一個閉包,因此,當函數運行時,方向將始終等於最后一個值(“右”)。

這是一個難看的固定版本:

    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        

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

是:

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

這將創建並運行一個匿名函數,該函數捕獲directionkey的值,以便bind回調可以使用它們。 有關更多信息,請參見我的PragProg文章A CoffeeScript干預

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM