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

- L’application des MiniDrones Parrot est aussi disponible pour Windows 8.1 par Blog de Jérémy Jeanson le 10-28-2014, 15:01

- L’application des MiniDrones Parrot est enfin disponible pour Windows Phone par Blog de Jérémy Jeanson le 10-27-2014, 09:49

- Mise à jour Samsung 840 EVO sur core server par Blog de Jérémy Jeanson le 10-27-2014, 05:59

- MVP Award 2014 ;) par Blog de Jérémy Jeanson le 10-27-2014, 05:42

- « Naviguer vers le haut » dans une librairie SharePoint par Blog de Jérémy Jeanson le 10-07-2014, 13:21

- PowerShell: Comment mixer NAGIOS et PowerShell pour le monitoring applicatif par Blog Technique de Romelard Fabrice le 10-07-2014, 11:43

- ReBUILD 2014 : les présentations par Le blog de Patrick [MVP Office 365] le 10-06-2014, 09:15

- II6 Management Compatibility présente dans Windows Server Technical Preview avec IIS8 par Blog de Jérémy Jeanson le 10-05-2014, 17:37

- Soft Restart sur Windows Server Technical Preview par Blog de Jérémy Jeanson le 10-03-2014, 19:43

- Non, le certificat public du CA n’est pas un certificat client !!! par Blog de Jérémy Jeanson le 10-03-2014, 00:08