Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1273 connectés 

  FORUM HardWare.fr
  Programmation
  HTML/CSS

  [JavaScript] problème de "closure" (résolut)

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[JavaScript] problème de "closure" (résolut)

n°1875793
ZeBorG
Yes we can!
Posté le 21-04-2009 à 11:56:06  profilanswer
 

Bonjour à tous,
 
j'ai un petit souci avec le passage de variable utilisé au sein d'une fonction: Du fait du "closure" (je ne connais pas le terme Français), je n'obtiens pas la variable escompté.  
 
Je vais donner un exemple simplifié:
 
Imaginons les structures suivantes:

Code :
  1. var actions = {
  2.    'UP': 1,
  3.    'DOWN': 2,
  4.    'LEFT': 3,
  5.    'RIGHT': 4
  6. };
  7.  
  8. var buttons = ['UP', 'DOWN', 'LEFT', 'RIGHT'];


Si je procède ainsi:

Code :
  1. for (var b in buttons) {
  2.    var index = actions[buttons[b]];
  3.    bindKey(buttons[b], function () { // bindKey() est une fonction que j'ai créer qui me permet d'associer à une touche un callback...
  4.        alert(index);
  5.    });
  6. }


Quand j'appuie sur les touches UP, DOWN, LEFT et RIGHT, alert(index) m'affiche toujours undefined car index c'est fait modifier entre temps (sorte de variable global dû au "closure"...)
 
Par contre, si je procède ainsi:

Code :
  1. function bindKey2(button, index){
  2.    bindKey(button, function () {
  3.        alert(index);
  4.    });
  5. }
  6.  
  7. for (var b in buttons) {
  8.    var index = actions[buttons[b]];
  9.    bindKey2(buttons[b], index);
  10. }

Dans ce cas, alert(index) m'affiche bien 1, 2, 3, 4 et non undefined. Ceci est du au fait que en appelant la fonction bindKey2, les variables passé en paramètre sont des instances de ces variable et non des références aux variables global.
 
Ma question est la suivante: Comment écrire ceci sans passer par une fonction intermédiaire (bindKey2 dans mon exemple)?


Message édité par ZeBorG le 23-04-2009 à 01:11:54
mood
Publicité
Posté le 21-04-2009 à 11:56:06  profilanswer
 

n°1876543
mIRROR
Chevreuillobolchévik
Posté le 22-04-2009 à 22:48:49  profilanswer
 

si c était juste un problème de closure t aurais pas 4 fois "4" plutot ?
je pense plutot que comme ta callback se lance sur un event ca décale ton scope
t as essayé de déclarer index au meme niveau que bindKey ?


---------------
« The enemy is the gramophone mind, whether or not one agrees with the record that is being played at the moment. » — George Orwell
n°1876549
SICKofitAL​L
misanthrope
Posté le 22-04-2009 à 23:04:47  profilanswer
 

à tester

 
Code :
  1. for (var b in buttons)
  2. {
  3.    var index = actions[buttons[b]];
  4.    bindKey.call (buttons[b], buttons[b], function () { alert (this) });
  5. }
 

[:_edit]
Ca marche pas :o
Tu as le code de ton bindKey ?


Message édité par SICKofitALL le 22-04-2009 à 23:18:20

---------------
We deserve everything that's coming...
n°1876579
SICKofitAL​L
misanthrope
Posté le 23-04-2009 à 00:04:07  profilanswer
 

Bon ca marche comme ca avec une vrai closure :

Code :
  1. for (var b in buttons)
  2. {
  3.    var index = actions[buttons[b]];
  4.    bindKey (buttons[b], (function () { var cIndex = index; return function () { alert (cIndex) } } ) () );
  5. }
 

cIndex devient une sorte de variable statique et c'est elle qu'on affiche plutot qu'index, qui a évolué entre l'instanciation de la fonction et son affichage.

 

[:_edit]
version plus lisible

Code :
  1. var f = function () { var cIndex = index; return function () { alert (cIndex) } };
  2. for (var b in buttons)
  3.   {
  4.     var index = actions[buttons[b]];
  5.     bindKey (buttons[b], f () );
  6.   }



Message édité par SICKofitALL le 23-04-2009 à 00:07:33

---------------
We deserve everything that's coming...
n°1876587
ZeBorG
Yes we can!
Posté le 23-04-2009 à 00:36:20  profilanswer
 

Je me disais bien que la réponse allait être évidente. Suffisait d'y penser ;)
 
Merci bien :)

n°1876588
SICKofitAL​L
misanthrope
Posté le 23-04-2009 à 00:40:15  profilanswer
 

De rien :)
Ca m'a permis de me rendre compte que je passais souvent bcp de temps à gérer le scope à coups de call et apply, alors que dans la majorité des cas, une bonne closure fait l'affaire :o


---------------
We deserve everything that's coming...
n°1876591
ZeBorG
Yes we can!
Posté le 23-04-2009 à 01:06:13  profilanswer
 

Pour que ce soit un peu plus claire dans ma tête j'ai externalisé la closure de la manière suivante:

Code :
  1. for (var b in buttons) {
  2.    (function () { // we create a closure in order to keep the current value of index at the time of the loop iteration
  3.        var index = actions[buttons[b]];
  4.        bindKey(buttons[b], function () {
  5.            alert(index);
  6.        });
  7.    })();
  8. }

Merci encore :)


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  HTML/CSS

  [JavaScript] problème de "closure" (résolut)

 

Sujets relatifs
[C][GTK] Problème de signal_connectProbleme de redirection avec OVH et classe
problème boucle whileProblème de (gros...) debutant
Problème de gestion de stock sous excel 2007[Problème] Instanciation de Servlet au démarrage de Tomcat
Probleme FMod, enchainement sans coupureProblème avec les variables globales, bug PHP !?
probleme de regex et preg_replacePetit problème macros VBA Excel
Plus de sujets relatifs à : [JavaScript] problème de "closure" (résolut)


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR