Cet article a été écrit à l’origine pour DigitalOcean.
le mot-clé this est un concept très important en JavaScript, et aussi particulièrement déroutant pour les nouveaux développeurs et ceux qui ont de l’expérience dans d’autres langages de programmation. En JavaScript, this est une référence à un objet., L’objet this fait référence peuvent varier, implicitement basée sur le fait qu’il est global, sur un objet, ou dans un constructeur, et peut également varier explicitement basé sur l’utilisation de la balise Function prototype des méthodes bind, call, et apply.
bien quethis soit un sujet un peu complexe, c’est aussi un sujet qui apparaît dès que vous commencez à écrire vos premiers programmes JavaScript., Que vous essayiez d’accéder à un élément ou à un événement dans le Document Object Model (DOM), de créer des classes pour écrire dans le style de programmation orientée objet ou d’utiliser les propriétés et les méthodes d’objets réguliers, vous rencontrerez this.
Dans cet article, vous allez apprendre ce qu’ this renvoie implicitement basée sur le contexte, et vous apprendrez à utiliser la balise bind, call, et apply méthodes explicitement déterminer la valeur de this.,
contexte implicite
Il existe quatre contextes principaux dans lesquels la valeur de this peut être implicitement déduite:
- le contexte global
- En tant que méthode dans un objet
- En tant que constructeur sur une fonction ou une classe
- En tant que gestionnaire/h3>
dans le contexte global,
thisfait référence à l’objet global. Lorsque vous travaillez dans un navigateur, le contexte global estwindow. Lorsque vous travaillez dans Node.js, le contexte global estglobal.,Remarque: Si vous n’êtes pas encore familier avec le concept de portée en JavaScript, veuillez consulter comprendre les Variables, la portée et le levage en JavaScript.
pour les exemples, vous pratiquerez le code dans la console Developer Tools du navigateur. Lisez comment utiliser la console de développement JavaScript si vous n’êtes pas familier avec l’exécution de code JavaScript dans le navigateur.
Si vous vous connectez à la valeur de
thissans aucun autre code, vous verrez que l’objetthisse réfère.,console.log(this)Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}Vous pouvez voir que
thisestwindow, qui est l’objet global d’un navigateur.en comprenant les Variables, la portée et le levage en JavaScript, vous avez appris que les fonctions ont leur propre contexte pour les variables. Vous pourriez être tenté de penser que
thissuivrait les mêmes règles à l’intérieur d’une fonction, mais ce n’est pas le cas. Une fonction de niveau supérieur conservera toujours la référencethisde l’objet global.,– Vous écrire une fonction de niveau supérieur, ou une fonction qui n’est pas associé avec n’importe quel objet, comme ceci:
function printThis() { console.log(this)}printThis()Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}Même à l’intérieur d’une fonction,
thisfait toujours référence à la balisewindow, ou de l’objet global.Cependant, lorsque vous utilisez le mode strict, le contexte de
thisà l’intérieur d’une fonction dans le contexte global seraundefined.,'use strict'function printThis() { console.log(this)}printThis()undefinedde manière générale, il est plus sûr d’utiliser le mode strict pour réduire la probabilité de
thisayant un imprévu portée. Il est rare que quelqu’un veuille faire référence à l’objetwindowen utilisantthis.pour plus d’informations sur le mode strict et les changements qu’il apporte concernant les erreurs et la sécurité, Lisez la documentation du mode Strict sur MDN.,
Une Méthode de l’Objet
Une méthode est une fonction sur un objet, ou une tâche que peut effectuer un objet. Une méthode utilise
thispour consulter les propriétés de l’objet."The United States of America was founded in 1776."Dans cet exemple, la balise
thisest leamerica.dans un objet imbriqué,
thisfait référence à la portée de l’objet actuel de la méthode. Dans l’exemple suivant,this.symboldans ledetailsobjet fait référence à l’details.symbol.,"The symbol is the eagle and the currency is USD."une Autre façon de penser, c’est que
thisfait référence à l’objet sur le côté gauche de la dot lors de l’appel d’une méthode.un constructeur de fonction
lorsque vous utilisez le mot-clé
new, il crée une instance d’une fonction ou d’une classe de constructeur. Les constructeurs de fonctions étaient le moyen standard d’initialiser un objet défini par l’utilisateur avant que la syntaxeclassne soit introduite dans la mise à jour ECMAScript 2015 de JavaScript., Dans comprendre les Classes en JavaScript, vous apprendrez à créer un constructeur de fonction et un constructeur de classe équivalent."The United States of America was founded in 1776."Dans ce contexte,
thisest maintenant lié à l’instance deCountry, qui est contenue dans la baliseamericaconstante.Un Constructeur de la Classe
Un constructeur d’une classe fonctionne de la même comme un constructeur sur une fonction. En savoir plus sur les similitudes et les différences entre les constructeurs de fonctions et les classes ES6 dans comprendre les Classes en JavaScript.,
thisdans ledescribeméthode fait référence à l’instance deCountryqui estamerica."The United States of America was founded in 1776."UN DOM Gestionnaire d’Événement
Dans le navigateur, il existe un
thisle contexte pour les gestionnaires d’événements. Dans un gestionnaire d’événement appelé paraddEventListener,thisva reportez-vous àevent.currentTarget., Le plus souvent, les développeurs utiliseront simplementevent.targetouevent.currentTargetau besoin pour accéder aux éléments du DOM, mais étant donné que les changements de référencethisdans ce contexte, il est important de savoir.Dans l’exemple suivant, nous allons créer un bouton, ajouter du texte, et l’ajouter à la DOM. Lorsque nous enregistrons la valeur de
thisdans le gestionnaire d’événements, il affiche la cible.,<button>Click me</button>une Fois que vous les coller dans votre navigateur, vous verrez un bouton ajouté à la page qui dit « Cliquez-moi ». Si vous cliquez sur le bouton, vous verrez
<button>Click me</button>apparaître dans votre console, car cliquer sur le bouton enregistre l’élément, qui est le bouton lui-même. Par conséquent, comme vous pouvez le voir,thisfait référence à l’élément ciblé, qui est l’élément auquel nous avons ajouté un écouteur d’événement.,contexte explicite
dans tous les exemples précédents, la valeur de
thisétait déterminée par son contexte—qu’il soit global, dans un objet, dans une fonction ou une classe construite, ou sur un gestionnaire D’événements DOM. Cependant, l’utilisation decall,applyoubind, vous pouvez explicitement déterminer cethisdoit se rapporter.,Il est difficile de définir exactement quand utiliser
call,applyoubind, car il dépendra du contexte de votre programme.bindpeut être particulièrement utile lorsque vous souhaitez utiliser les événements pour accéder aux propriétés d’une classe dans une autre. Par exemple, si vous deviez écrire un jeu simple, vous pourriez séparer l’interface utilisateur et les E/S dans une classe, et la logique et l’état du jeu dans une autre., Étant donné que la logique du jeu aurait besoin d’accéder à l’entrée, telle qu’une pression sur une touche et un clic, vous voudriezbindles événements pour accéder à lathisvaleur de la classe logique du jeu.la partie importante est de savoir comment déterminer à quel objet
thisfait référence, ce que vous pouvez faire implicitement avec ce que vous avez appris dans les sections précédentes, ou explicitement avec les trois méthodes que vous apprendrez ensuite.,Appel et s’Appliquent
calletapplysont très similaire—ils appeler une fonction avec un certainthisle contexte et les arguments optionnels. La seule différence entrecalletapplyquecallrequiert les arguments passés à un par un, etapplyprend les arguments dans un tableau.,dans cet exemple, nous allons créer un objet et créer une fonction qui fait référence à
thismais n’a pas de contextethis."undefined was written by undefined"Depuis
summaryetbookn’ont pas de lien, en invoquantsummarypar lui-même ne printundefined, comme il est à la recherche de ces propriétés sur l’objet global.,Remarque: vous essayez cela en mode strict entraînerait
Uncaught TypeError: Cannot read property 'title' of undefined,thisseraitundefined.Cependant, vous pouvez utiliser
calletapplypour appeler lethiscontextebooksur la fonction.,summary.call(book)// or:summary.apply(book)"Brave New World was written by Aldous Huxley."Il y a maintenant un lien entre
booketsummarylorsque ces méthodes sont appliquées. Confirmons exactement ce qu’estthis.function printThis() { console.log(this)}printThis.call(book)// or:whatIsThis.apply(book){title: "Brave New World", author: "Aldous Huxley"}Dans ce cas, la balise
thisen fait, devient l’objet passé en argument.c’est de Cette façon
calletapplysont les mêmes, mais il y a une petite différence., En plus de pouvoir passer le contextethiscomme premier argument, vous pouvez également passer des arguments supplémentaires.function longerSummary(genre, year) { console.log( `${this.title} was written by ${this.author}. It is a ${genre} novel written in ${year}.`, )}Avec des
callchaque valeur supplémentaire que vous souhaitez passer est envoyé comme un argument supplémentaire.,longerSummary.call(book, 'dystopian', 1932)"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."Si vous essayez d’envoyer exactement les mêmes arguments avec des
apply, c’est ce qui se passe:longerSummary.apply(book, 'dystopian', 1932)Uncaught TypeError: CreateListFromArrayLike called on non-object at <anonymous>:1:15Plutôt pour
apply, vous devez passer tous les arguments dans un tableau.longerSummary.apply(book, )"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."La différence entre passer les arguments individuellement ou dans un tableau, c’est subtil, mais il est important d’être conscient de., Il pourrait être plus simple et plus pratique d’utiliser
apply, car il ne nécessiterait pas de changer l’appel de fonction si certains détails de paramètres changeaient.Bind
les Deux
calletapplyune fois l’utilisation de méthodes—si vous appelez la méthode avec la balisethiscontexte, il va l’avoir, mais la fonction d’origine reste inchangé.,parfois, vous devrez peut-être utiliser une méthode encore et encore avec le contexte
thisd’un autre objet, et dans ce cas, vous pouvez utiliser labindpour créer une toute nouvelle fonction avec unthisexplicitement lié.const braveNewWorldSummary = summary.bind(book)braveNewWorldSummary()"Brave New World was written by Aldous Huxley"Dans cet exemple, chaque fois que vous appelez
braveNewWorldSummary, il retournera toujours l’originalthisvaleur lié à elle., Tenter de lier un nouveau contextethiséchouera, vous pouvez donc toujours faire confiance à une fonction liée pour renvoyer la valeurthisque vous attendez.bien que cet exemple essaie de lier
braveNewWorldSummaryune fois de plus, il conserve le contexte originalthisde la première fois qu’il a été lié.Flèche Fonctions
Flèche fonctions n’ont pas leur propre
thisliaison. Au lieu de cela, ils vont au prochain niveau d’exécution.,Il peut être utile d’utiliser la fonction flèche dans les cas où vous voulez vraiment
thispour faire référence au contexte externe. Par exemple, si vous aviez un écouteur d’événement à l’intérieur d’une classe, vous voudriez probablement quethisfasse référence à une valeur de la classe.dans cet exemple, vous allez créer et Ajouter un bouton au DOM comme précédemment, mais la classe aura un écouteur d’événement qui changera la valeur de texte du bouton lorsque vous cliquez dessus.
Si vous cliquez sur le bouton, le contenu du texte passera à la valeur
buttonText., Si vous n’aviez pas utilisé une fonction de flèche ici,thisserait égal àevent.currentTarget, et vous ne pourriez pas l’utiliser pour accéder à une valeur dans la classe sans la lier explicitement. Cette tactique est souvent utilisée sur les méthodes de classe dans des frameworks comme React.Conclusion
dans cet article, vous avez appris à propos de
thisen JavaScript, et les nombreuses valeurs différentes qu’il pourrait avoir basées sur la liaison d’exécution implicite, et la liaison explicite viabind,call, etapply., Vous avez également appris comment l’absence de liaisonthisdans les fonctions arrow peut être utilisée pour faire référence à un contexte différent. Avec cette connaissance, vous devriez être en mesure de déterminer la valeur dethisdans vos programmes.