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

- Server Essentials 2016 et site remote web access indisponible par Blog de Jérémy Jeanson le 12-09-2016, 13:10

- Office 365: Utiliser les alertes dans SharePoint Online par Blog Technique de Romelard Fabrice le 11-30-2016, 12:45

- Windows: Comment comparer les outils de copie de fichiers disponibles en mode console avec un script PowerShell par Blog Technique de Romelard Fabrice le 11-18-2016, 11:17

- TFS 2017 est disponible ! par Blog de Jérémy Jeanson le 11-17-2016, 08:04

- Office 365: Configurer l’ouverture des fichiers dans Office Web Apps pour une Librarie Documentaire par Blog Technique de Romelard Fabrice le 11-15-2016, 17:14

- Office 365: Comment gérer les Access Requests dans les sites SharePoint Online par Blog Technique de Romelard Fabrice le 11-10-2016, 15:11

- Windows 2008 R2: Réduire la taille du répertoire system volume information par Blog Technique de Romelard Fabrice le 11-07-2016, 10:01

- UWP et langues indisponibles ? par Blog de Jérémy Jeanson le 11-04-2016, 12:54

- Impossible de se connecter à Windows Server Essentials 2016 par Blog de Jérémy Jeanson le 10-29-2016, 09:55

- Changer la langue d’un Windws Server Core 2016 par Blog de Jérémy Jeanson le 10-27-2016, 17:51