Comprendre pleinement le mot-clé this

Le tutoriel d'aujourd'hui est une gracieuseté du talentueux Cody Lindley, extrait de son ebook gratuit: JavaScript Enlightenment. Il discute de la confusion ce mot-clé, et les différentes façons de déterminer et de définir sa valeur.

Tutoriel republié

Toutes les quelques semaines, nous revoyons certains des articles préférés de nos lecteurs tout au long de l'histoire du site. Ce tutoriel a été publié pour la première fois en juillet 2011..


Aperçu conceptuel de ce

Lors de la création d'une fonction, un mot clé appelé celui-ci est créé (en coulisse), qui renvoie à l'objet dans lequel la fonction est utilisée. Autrement dit, cela est disponible pour l'étendue de sa fonction, mais il s'agit d'une référence à l'objet dont cette fonction est une propriété / méthode..

Jetons un coup d'oeil à cet objet:

 

Observez comment à l'intérieur de la obtenirGender fonction, nous accédons à la propriété genre en utilisant la notation par points (par exemple, cody.gender) sur l'objet cody lui-même. Ceci peut être réécrit en utilisant ce accéder au Cody objet parce que ce pointe vers le Cody objet.

 

le ce utilisé dans this.gender se réfère simplement à la Cody objet sur lequel la fonction est
en fonctionnement.

Le sujet de ce peut être déroutant, mais cela ne doit pas nécessairement l'être. Rappelez-vous simplement qu'en général, ce est utilisé dans les fonctions pour faire référence à l'objet dans lequel la fonction est contenue, par opposition à la fonction elle-même (les exceptions incluent l'utilisation de Nouveau mot clé ou appel() et appliquer()).

Notes IMPORTANTES

  • Le mot clé ce ressemble à n'importe quelle autre variable, sauf que vous ne pouvez pas la modifier.
  • - Par opposition à arguments et tous les paramètres envoyés à la fonction, ce est un mot clé (pas une propriété) dans l'objet call / activation.

Comment est la valeur de ce Déterminé?

La valeur de ce, passé à toutes les fonctions, est basé sur le contexte dans lequel la fonction est appelée à l'exécution. Faites attention ici, car c’est l’une de ces bizarreries qu'il vous suffit de mémoriser.

le monObjet objet dans le code ci-dessous est donné une propriété appelée sayFoo, qui pointe vers le sayFoo une fonction. Quand le sayFoo La fonction est appelée à partir de la portée globale, elle fait référence à l’objet window. Quand on l'appelle comme méthode de monObjet, ce fait référence à monObjet.

Incedès monObjet a une propriété nommée foo, cette propriété est utilisée.

 

Clairement, la valeur de ce est basé sur le contexte dans lequel la fonction est appelée. Considérer que les deux myObject.sayFoo et sayFoo pointez sur la même fonction. Cependant, en fonction de l'endroit (c'est-à-dire du contexte) sayFoo () est appelé à partir de, la valeur de ce est différent.

Si cela vous aide, voici le même code avec l'objet head (c'est-à-dire la fenêtre) explicitement utilisé.

 

Assurez-vous que lorsque vous transmettez des fonctions ou que vous avez plusieurs références à une fonction, vous réalisez que la valeur de ce changera en fonction du contexte dans lequel vous appelez la fonction.

Note importante

  • Toutes les variables sauf ce et les arguments suivent la portée lexicale.

le ce Le mot-clé fait référence à l'objet Head dans les fonctions imbriquées.

Vous vous demandez peut-être ce qui se passe ce quand il est utilisé à l'intérieur d'une fonction qui est contenue à l'intérieur d'une autre fonction. La mauvaise nouvelle est dans ECMA 3, ce perd son chemin et fait référence à l’objet de la tête (la fenêtre objet dans les navigateurs), au lieu de l'objet dans lequel la fonction est définie.


Dans le code ci-dessous, ce à l'intérieur de func2 et func3 perd son chemin et se réfère pas à monObjet mais à la tête de l'objet.

 

La bonne nouvelle est que cela sera corrigé dans ECMAScript 5. Pour l'instant, vous devez être conscient de cette situation, en particulier lorsque vous commencez à transmettre des fonctions en tant que valeurs à d'autres fonctions..

Considérez le code ci-dessous et ce qui se passe lorsque vous passez une fonction anonyme à foo.func1. Lorsque la fonction anonyme est appelée à l'intérieur de foo.func1 (une fonction à l'intérieur d'une fonction) la ce la valeur à l'intérieur de la fonction anonyme sera une référence à l'objet head.

 

Maintenant, vous n'oublierez jamais: le ce valeur sera toujours une référence à l'objet head lorsque sa fonction hôte est encapsulée dans une autre fonction ou appelée dans le contexte d'une autre fonction (là encore, cela est corrigé dans ECMAScript 5).


Contournement du problème de fonction imbriquée

De sorte que la ce la valeur ne soit pas perdue, vous pouvez simplement utiliser la chaîne de la portée pour conserver une référence à ce dans la fonction parent. Le code ci-dessous montre comment, à l’aide d’une variable appelée cette, et en tirant parti de sa portée, nous pouvons mieux suivre le contexte de la fonction.


Contrôler la valeur de ce

La valeur de ce est normalement déterminé à partir du contexte dans lequel une fonction est appelée (sauf lorsque le Nouveau mot-clé est utilisé - plus à ce sujet dans une minute), mais vous pouvez écraser / contrôler la valeur de ce en utilisant appliquer() ou appel() définir quel objet ce pointe vers lors de l'appel d'une fonction. Utiliser ces méthodes revient à dire: "Hé, appelle la fonction X mais indique à la fonction d’utiliser un objet Z comme valeur pour ce."Ce faisant, la manière par défaut avec laquelle JavaScript détermine la valeur de ce est annulé.

Ci-dessous, nous créons un objet et une fonction. Nous appelons ensuite la fonction via appel() de sorte que la valeur de ce à l'intérieur de la fonction utilise monObjet comme son contexte. Les déclarations à l'intérieur du ma fonction la fonction sera alors peuplée monObjet avec des propriétés au lieu de remplir l'objet principal. Nous avons modifié l'objet auquel ce (à l'intérieur de ma fonction) fait référence.

 

Dans l'exemple ci-dessus, nous utilisons appel(), mais appliquer() pourrait être utilisé aussi bien. La différence entre les deux réside dans la manière dont les paramètres de la fonction sont passés. En utilisant appel(), les paramètres sont juste des valeurs séparées par des virgules. En utilisant appliquer(), les valeurs de paramètre sont passées à l'intérieur d'un tableau. Ci-dessous, la même idée, mais en utilisant appliquer().

 

Ce que vous devez retenir ici, c'est que vous pouvez remplacer la manière par défaut avec laquelle JavaScript détermine la valeur de ce dans la portée d'une fonction.


En utilisant le ce Mot-clé dans une fonction constructeur définie par l'utilisateur

Lorsqu'une fonction est appelée avec le Nouveau mot-clé, la valeur de ce - comme il est indiqué dans le constructeur - fait référence à l'instance elle-même. En d'autres termes: dans la fonction constructeur, nous pouvons exploiter l'objet via ce avant que l'objet soit réellement créé. Dans ce cas, la valeur par défaut de ce des changements d'une manière pas à la différence d'utiliser appel() ou appliquer().

Ci-dessous, nous mettons en place un La personne fonction constructeur qui utilise ce faire référence à un objet en cours de création. Quand une instance de La personne est créé, Ce nom référencera l'objet nouvellement créé et placera une propriété appelée prénom dans le nouvel objet avec une valeur du paramètre (prénom) passé à la fonction constructeur.

 

Encore, ce fait référence à "l'objet qui doit être" lorsque la fonction constructeur est appelée à l'aide de la commande Nouveau mot-clé. Si nous n'avions pas utilisé le Nouveau mot-clé, la valeur de ce serait le contexte dans lequel la personne est invoquée - dans ce cas, l'objet principal. Examinons ce scénario.

 

Le mot clé ce Dans une méthode prototype Fait référence à une instance de constructeur

Lorsqu'il est utilisé dans des fonctions ajoutées à un constructeur prototype propriété, ce fait référence à l'instance sur laquelle la méthode est appelée. Disons que nous avons une coutume La personne() fonction constructeur. En tant que paramètre, il nécessite le nom complet de la personne. Si nous devons accéder au nom complet de la personne, nous ajoutons un whatIsMyFullName méthode à la Person.prototype, pour que tout La personne les instances héritent de la méthode. Lors de l'utilisation ce, la méthode peut faire référence à l'instance qui l'invoque (et donc à ses propriétés).

Ici, je montre la création de deux La personne objets (Cody et Lisa) et l'héritage whatIsMyFullName méthode qui contient le mot-clé this pour accéder à l'instance.

 

Le emporter ici est que le mot clé ce est utilisé pour faire référence à des instances lorsqu'il est utilisé à l'intérieur d'une méthode contenue dans la prototype objet. Si l'instance ne contient pas la propriété, la recherche de prototype commence.

Remarques

- Si l'instance ou l'objet pointé par ce ne contient pas la propriété référencée, les mêmes règles que pour toute recherche de propriété sont appliquées et la propriété sera "recherchée" sur la chaîne de prototypes. Donc, dans notre exemple, si le nom complet la propriété n'a pas été contenue dans notre instance alors nom complet serait recherché à Person.prototype.fullName puis Object.prototype.fullName.


Lire le livre gratuitement!

Ce livre ne traite pas des modèles de conception JavaScript ni de la mise en œuvre d'un paradigme orienté objet avec du code JavaScript. Il n'a pas été écrit pour distinguer les bonnes caractéristiques du langage JavaScript des mauvaises. Il ne s'agit pas d'un guide de référence complet. Il n'est pas destiné aux personnes novices en programmation ou à celles complètement nouvelles en JavaScript. Ce n'est pas non plus un livre de recettes de recettes JavaScript. Ces livres ont été écrits.