2013-06-20 4 views
6

Je suis en train d'utiliser le plugin javascript mousetrap pour gérer quelques coups clés de la même façon, donc je pensais que les coder comme suit:accès à la variable mutable dans une fermeture d'événement

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); 
     })); 

    } 

Mais, de toute évidence, i est mutable. Cependant, je ne suis pas sûr de savoir comment écrire une fermeture où je concurrence le paramètre d'événement dans la réponse. Suggestions sur la façon de gérer cette situation?

+0

vous souhaitez utiliser l'événement dans le gestionnaire d'attributs? Je n'ai pas bien compris "en compétition" dans ce contexte désolé. – Edorka

+0

Montrez-nous ce que vous avez essayé. Quel était le problème avec le paramètre d'événement? La fermeture IEFE doit renvoyer la fonction gestionnaire qui accepte le paramètre 'e'. – Bergi

Répondre

5

comment écrire une fermeture où je suis en compétition le paramètre d'événement dans la réponse

Utilisation d'une fermeture soit autour de l'ensemble du corps de boucle (comme @dandavis) ont montré), ou l'utiliser seulement autour le gestionnaire:

… 
    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

vous devez envelopper la variable i dans une portée locale afin qu'il ne se synchronise pas avec le « i » dans la boucle:

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)); 
    } 

l'autre alternative est d'utiliser des méthodes de tableaux fonctionnels, qui car ils utilisent des fonctions, ont toujours leur portée, et ils fournissent la valeur de l'élément et l'indice de l'élément vous intrinsèquement:

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() 

le 2ème exemple fonctionnera de la boîte à IE9 +, mais vous pouvez le faire fonctionner partout avec un simple module de compilation de méthode Array, généralement inclus dans les shims IE. .

Questions connexes