⊗jsPmTrTCL 451 of 505 menu

Minuteurs et perte de contexte en JavaScript

Lors de l'utilisation de minuteries dans les gestionnaires d'événements, nous sommes confrontés à des problèmes de perte de contexte. Regardons un exemple.

Supposons que nous ayons un champ de saisie :

<input id="elem" value="text">

Supposons qu'un clic sur ce champ déclenche une fonction anonyme et qu'à l'intérieur de cette fonction, une minuterie se mette en marche, affichant quelque chose dans la console chaque seconde :

let elem = document.querySelector('#elem'); elem.addEventListener('click', function() { setInterval(function() { console.log('!!!'); // nous affichons quelque chose dans la console }, 1000); });

Jusqu'ici, tout fonctionne correctement. Mais supposons maintenant que nous voulions afficher la value de notre champ dans la console - une surprise nous attend : la console affichera undefined :

elem.addEventListener('click', function() { setInterval(function() { console.log(this.value); // affichera undefined }, 1000); });

Le problème est que nous nous retrouvons avec une fonction dans une fonction : il y a une fonction anonyme externe, qui est appelée lors du clic, et une fonction anonyme interne, qui est lancée par la minuterie. Dans la fonction externe, this fait référence au champ de saisie, mais pas dans la fonction interne. C'est une perte de contexte.

Pourquoi undefined est-il affiché, et non une erreur dans la console, comme cela s'est produit dans les leçons précédentes ? Parce que this à l'intérieur de la fonction appelée via setInterval fait référence à window.

Cela signifie que nous essayons de lire la propriété value de l'objet window, comme ceci : window.value, or une telle propriété n'existe pas, et nous obtenons undefined (pas une erreur).

Corrigeons le problème en introduisant self :

elem.addEventListener('click', function() { let self = this; setInterval(function() { console.log(self.value); }, 1000); });

Supposons le code suivant :

<input type="button" id="elem" value="1"> let elem = document.querySelector('#elem'); elem.addEventListener('click', function() { setInterval(function() { this.value = Number(elem.value) + 1; }, 1000); });

L'auteur du code souhaitait qu'en cliquant sur le bouton, la valeur de ce bouton augmente de 1 chaque seconde. Cependant, rien ne se passe lors du clic sur le bouton. Corrigez l'erreur de l'auteur du code. Écrivez un texte dans lequel vous expliquerez à l'auteur du code pourquoi son erreur s'est produite.

Français
AfrikaansAzərbaycanБългарскиবাংলাБеларускаяČeštinaDanskDeutschΕλληνικάEnglishEspañolEestiSuomiहिन्दीMagyarՀայերենIndonesiaItaliano日本語ქართულიҚазақ한국어КыргызчаLietuviųLatviešuМакедонскиMelayuမြန်မာNederlandsNorskPolskiPortuguêsRomânăРусскийසිංහලSlovenčinaSlovenščinaShqipСрпскиSrpskiSvenskaKiswahiliТоҷикӣไทยTürkmenTürkçeЎзбекOʻzbekTiếng Việt
Nous utilisons des cookies pour le fonctionnement du site, l'analyse et la personnalisation. Le traitement des données est effectué conformément à la Politique de confidentialité.
accepter tout personnaliser refuser