Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Atteint de JavaScriptite Aiguë [Cyril Durand]

Expert ASP.net Ajax et WCF, Cyril Durand parle dans son blog de point techniques sur ASP.net, ASP.net Ajax, JavaScript, WCF et .net en général. Cyril est également consultant indépendant, n'hésitez pas à le contacter pour de l'assistance sur vos projets

Actualités

  • Blog de Cyril DURAND, passionné de JavaScript, Ajax, ASP.net et tout ce qui touche au developpement Web Client-Side.

    N'hésitez pas à me contacter pour vos projets .net : architecture, accompagnement, formation, ...

    View Cyril Durand's profile on LinkedIn
    hit counters


    Expertise Commerce server et BizTalk

Quizz JavaScript : réponse gestionnaire d'evenements et boucle

Voici la réponse au Quizz JavaScript - gestionnaire d'evenements et boucles.

Pour rappel la question était pourquoi lorsque l'on click sur un bouton créé avec le code ci-dessous, il nous affiche toujours 'button N°10' ?

var div = $get('div1'); for (var i = 0; i < 10; i++){ var btn = document.createElement('button'); btn.appendChild(document.createTextNode('button N°' + i)); btn.onclick = function(){ alert('button N°' + i); } div.appendChild(btn); div.appendChild(document.createElement('br')); }

C'est en fait un problème de scope, il faut savoir que la portée des variables en js est global à la fonction, c'est à dire que le i se trouvant dans le onclick est le même que celui de la boucle for. C'est au moment où l'on click sur un bouton que la fonction est interprété, i se rapportera toujours au i de la boucle for, c'est pour cela que i vaut 10 alors que le dernier boutton a pour texte "button N°9". Pour contourner le problème il faut créer un nouveau contexte de scope c'est à dire éxecuter une nouvelle function.

btn.onclick = function(j){ return function(){ alert(j); } }(i);

Ce code exécute une fonction qui retourne une fonction, comme il y a exécution de fonction, nous avons un nouveau contexte et donc une nouveau scope.

Microsoft Ajax Library possède une fonction qui fait exactement la même chose qu'au dessus : Function.createCallback (non documenté ...)

btn.onclick = Function.createCallback(function(j){ Sys.Debug.trace(j); }, i);

Il existe une autre astuce qui consiste à utiliser un expando attribute. JavaScript étant un langage dynamique on peut modifier le type d'un objet à la volée et donc rajouter une propriété comme on veut. C'est la solution la plus courante car la plus simple à comprendre.

btn.__i = i; btn.onclick = function(){ alert(this.__i); }

Il existe enfin une dernière solution que je déconseille, il s'agit de créer une function en utilisant le constructeur de l'objet Function ou à l'aide de la méthode eval (le constructeur de Function utilise eval en interne). 

btn.onclick = new Function('alert(' + i + ')');

Je déconseille cette solution pour deux raisons : d'une part niveau perf, eval est une fonction très couteuse. D'autre part puisque l'on définit la fonction à partir d'un string il faut que l'objet que l'on veut passer (i dans notre exemple) soit représentable sous la forme d'un string. Ce qui n'est pas forcément le cas pour des objets complexes.

Pour en savoir plus : Scope in JavaScript et Understanding scope and binding in JavaScript

Félicitation à Simon Ferquel, gldfdp, FremyCompany d'avoir trouvé les bonnes réponses.

Posted: dimanche 12 août 2007 16:54 par cyril
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

Pas de commentaires

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Créer un périphérique Windows To Go 10 ! par Blog de Jérémy Jeanson le 11-21-2014, 04:54

- RDV à Genève le 12 décembre pour l’évènement “SharePoint–Office 365 : des pratiques pour une meilleure productivité !” par Le blog de Patrick [MVP Office 365] le 11-19-2014, 10:40

- [IIS] Erreurs web personnalisées par Blog de Jérémy Jeanson le 11-19-2014, 00:00

- BDD/TDD + Javascript par Fathi Bellahcene le 11-16-2014, 16:57

- Sécuriser sans stocker de mots de passe par Blog de Jérémy Jeanson le 11-15-2014, 08:58

- Où télécharger la preview de Visual Studio 2015 ? par Blog de Jérémy Jeanson le 11-13-2014, 21:33

- Les cartes sont partout ! par Le blog de Patrick [MVP Office 365] le 11-13-2014, 17:26

- [ #Office365 ] Courrier basse priorité ! par Le blog de Patrick [MVP Office 365] le 11-12-2014, 08:56

- [Oracle] Fichier oranfsodm12.dll absent du package client par Blog de Jérémy Jeanson le 11-10-2014, 20:44

- [ #Office365 ] Le chapitre 1 des Groupes est écrit, et alors ? par Le blog de Patrick [MVP Office 365] le 11-10-2014, 20:23