2013-06-20 33 views
6

我試圖使用mousetrap JavaScript的插件來處理一些擊鍵以類似的方式,所以我認爲如下他們編寫了起來:訪問可變變量在事件關閉

var keys = [ 'b', 'i', 'u']; 
    for (var i=0; i < 3; ++i) { 
     var iKey = keys[i]; 
     var iKeyUpper = iKey.toUpperCase(); 

     Mousetrap.bind(
      [ 'command+' + iKey, 
       'command+' + iKeyUpper, 
       'ctrl+' + iKey, 
       'ctrl+' + iKeyUpper], 
      (function(e) { 
       console.log("you clicked: " + i); 
     })); 

    } 

但是,很明顯, i是可變的。但是,我不確定如何在響應中競爭事件參數時編寫閉包。如何處理這種情況的建議?

+0

您想在屬性處理程序中使用該事件嗎?在這種情況下,我不太明白「競爭」對不起。 – Edorka

+0

向我們展示你的嘗試。事件參數有什麼問題?閉包IEFE應該返回接受'e'參數的處理函數。 – Bergi

回答

5

如何寫一個封閉我在哪裏競爭事件參數的響應

使用封閉要麼圍繞整個循環體(如@dandavis)證明),或大約只有使用它處理程序:

… 
    Mousetrap.bind(
     [ 'command+' + iKey, 
      'command+' + iKeyUpper, 
      'ctrl+' + iKey, 
      'ctrl+' + iKeyUpper], 
     (function(_i) { // of course you can use the name `i` again 
      return function(e) { 
       console.log("you clicked: " + _i); 
      }; 
     })(i) // and pass in the to-be-preserved values 
    ); 
4

你需要用變量i在本地範圍,使得其不會與同步的「i」的for循環:

var keys = [ 'b', 'i', 'u']; 
    for (var i=0; i < 3; ++i) { 
     (function(i){ 
     var iKey = keys[i]; 
     var iKeyUpper = iKey.toUpperCase(); 

     Mousetrap.bind(
      [ 'command+' + iKey, 
       'command+' + iKeyUpper, 
       'ctrl+' + iKey, 
       'ctrl+' + iKeyUpper], 
      (function(e) { 
       console.log("you clicked: " + i); 
     })); 
     }(i)); 
    } 

另一替代方案是使用功能陣列的方法,這因爲它們使用的功能,總有自己的範圍,它們本質上提供的元素值和元素索引你:

var keys = [ 'b', 'i', 'u']; 
    keys.map(function(iKey, i){ 
     var iKeyUpper = iKey.toUpperCase(); 

     Mousetrap.bind(
      [ 'command+' + iKey, 
       'command+' + iKeyUpper, 
       'ctrl+' + iKey, 
       'ctrl+' + iKeyUpper], 
      function(e) { 
       console.log("you clicked: " + i); 
     }); // end bind()  

    }); // end map() 

第二個示例將工作在IE9 +盒子出來,但你可以把它在任何地方工作用一個簡單的下拉式Array方法compat包,通常包含在IE墊片中。 。