Maison >interface Web >js tutoriel >Pourquoi les boucles Javascript provoquent-elles un comportement inattendu dans les gestionnaires d'événements ?

Pourquoi les boucles Javascript provoquent-elles un comportement inattendu dans les gestionnaires d'événements ?

DDD
DDDoriginal
2024-12-22 06:26:38321parcourir

Why Do Javascript Loops Cause Unexpected Behavior in Event Handlers?

Le fameux problème de boucle Javascript revisité

Le fameux problème de boucle en Javascript continue de dérouter les développeurs. Considérez l'extrait de code suivant :

function addLinks () {
    for (var i=0, link; i<5; i++) {
        link = document.createElement("a");
        link.innerHTML = "Link " + i;
        link.onclick = function () {
            alert(i);
        };
        document.body.appendChild(link);
    }
}

Ce code est destiné à créer 5 liens, chacun avec un événement onClick qui affiche l'ID de lien actuel. Cependant, lorsque l'on clique sur ces liens, ils affichent tous le « lien 5 ».

La cause première de ce problème réside dans la portée au niveau des fonctions de Javascript. Une fois la boucle terminée, la variable i conserve la valeur 5. En effet, les fonctions Javascript sont fermées sur leur environnement lexical, ce qui signifie qu'elles ont accès aux variables définies dans la portée environnante.

Une solution de contournement à ce problème consiste à introduire une fermeture qui capture la valeur actuelle de i pour chaque itération :

function addLinks () {
    for (var i=0, link; i<5; i++) {
        link = document.createElement("a");
        link.innerHTML = "Link " + i;
        link.onclick = function (num) {
            return function () {
                alert(num);
            };
        }(i);
        document.body.appendChild(link);
    }
}

Dans ce code, un nouvel objet fonction est créé pour chaque lien. Il a sa propre portée et une variable locale num, à laquelle est attribuée la valeur actuelle de i. Lorsque la fonction interne est exécutée, elle fait référence à la variable num de la fermeture, qui conserve la valeur correcte attribuée dans la boucle.

Bien que cette approche soit efficace, elle entraîne une pénalité de performances lorsqu'une nouvelle fonction est créée pour chaque auditeur d'événement. Une alternative plus efficace consiste à utiliser le nœud DOM lui-même pour le stockage des données :

function linkListener() {
    alert(this.i);
}

function addLinks () {
    for(var i = 0; i < 5; ++i) {
        var link = document.createElement('a');
        link.appendChild(document.createTextNode('Link ' + i));
        link.i = i;
        link.onclick = linkListener;
        document.body.appendChild(link);
    }
}

En stockant la valeur i directement sur le nœud DOM, nous éliminons le besoin de fermetures, améliorant ainsi l'efficacité du code.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn