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

- SharePoint 20XX: Script PowerShell pour exporter en CSV toutes les listes d’une ferme pour auditer le contenu avant migration par Blog Technique de Romelard Fabrice le 03-28-2017, 17:53

- Les pièges de l’installation de Visual Studio 2017 par Blog de Jérémy Jeanson le 03-24-2017, 13:05

- UWP or not UWP sur Visual Studio 2015 ? par Blog de Jérémy Jeanson le 03-08-2017, 19:12

- Désinstallation de .net Core RC1 Update 1 ou SDK de Core 1 Preview 2 par Blog de Jérémy Jeanson le 03-07-2017, 19:29

- Office 365: Ajouter un utilisateur ou groupe dans la liste des Site collection Administrator d’un site SharePoint Online via PowerShell et CSOM par Blog Technique de Romelard Fabrice le 02-24-2017, 18:52

- Office 365: Comment créer une document library qui utilise les ContentTypeHub avec PowerShell et CSOM par Blog Technique de Romelard Fabrice le 02-22-2017, 17:06

- [TFS] Supprimer en masse les dépendances à SQL Enterprise ou Developer avant de procéder à une migration par Blog de Jérémy Jeanson le 02-20-2017, 20:30

- Office 365: Attention au volume utilisé par les fichiers de Thèmes de SharePoint Online par Blog Technique de Romelard Fabrice le 02-07-2017, 18:19

- [SCVMM] Supprimer une machine bloquée par Blog de Jérémy Jeanson le 01-31-2017, 21:22

- Microsoft .Net Challenge 2017 par Le Blog (Vert) d'Arnaud JUND le 01-30-2017, 15:25