JavaScript est un langage multi-paradigme qui prend en charge la programmation orientée objet et la liaison de méthode dynamique - un concept puissant qui permet à la structure du code JavaScript de changer pendant l'exécution du programme. Cela donne aux développeurs de sérieuses opportunités, cela rend le langage flexible, mais vous devez payer pour tout. Dans ce cas, vous devez payer avec l'intelligibilité du code. Une contribution significative à ce prix est apportée par le 
this , autour du comportement duquel beaucoup de choses ont été collectées qui peuvent dérouter le programmeur.

Liaison de méthode dynamique
La liaison dynamique vous permet de spécifier, lors de l'exécution du programme, et non lors de la compilation, la méthode qui doit être appelée lors de l'exécution d'une certaine commande. En JavaScript, ce mécanisme est implémenté à l'aide du 
this et de la chaîne de prototypes. En particulier, la valeur spécifique de 
this à l'intérieur de la méthode est déterminée lors de l'exécution et les règles de détermination de cette valeur varient en fonction de la façon dont la méthode a été déclarée.
Jouons un jeu. Je l'appelle "Qu'est-ce qui est écrit ici?". Voici sa première option - le code du module ES6:
 const a = { a: 'a' }; const obj = { getThis: () => this, getThis2 () {   return this; } }; obj.getThis3 = obj.getThis.bind(obj); obj.getThis4 = obj.getThis2.bind(obj); const answers = [ obj.getThis(), obj.getThis.call(a), obj.getThis2(), obj.getThis2.call(a), obj.getThis3(), obj.getThis3.call(a), obj.getThis4(), obj.getThis4.call(a) ]; 
Avant de continuer à lire, réfléchissez à ce qui se trouvera dans le tableau des réponses et notez les réponses. Après cela, testez-vous en 
answers tableau de 
answers aide de 
console.log() . Avez-vous réussi à «décrypter» correctement la valeur de 
this dans chacun des cas?
Nous analyserons ce problème, en commençant par le premier exemple. La construction 
obj.getThis() renvoie 
undefined . Pourquoi? Cette fonction de flèche ne peut pas être liée. Ces fonctions utilisent 
this partir de leur portée lexicale environnante. La méthode est appelée dans le module ES6, dans sa portée lexicale 
this ne sera pas 
undefined . Pour la même raison, 
undefined renverra 
undefined un appel à 
obj.getThis.call(a) . La valeur de 
this lorsque vous travaillez avec des fonctions fléchées ne peut pas être réaffectée même avec 
.call() ou 
.bind() . Cette valeur correspondra toujours à 
this partir de la portée lexicale, dans laquelle ces fonctions sont situées.
La commande 
obj.getThis2() montre comment travailler avec 
this lors de l'utilisation de méthodes d'objet normales. Si 
this pas lié à une méthode similaire, et à condition que cette méthode ne soit pas une fonction de flèche, c'est-à-dire qu'elle prend en charge 
this liaison, le mot clé 
this est lié à l'objet pour lequel la méthode est appelée en utilisant la syntaxe d'accès aux propriétés de l'objet via point ou en utilisant des crochets.
La construction 
obj.getThis2.call(a) est déjà un peu plus délicate à comprendre. La méthode 
call() vous permet d'appeler une fonction avec une valeur donnée de 
this , qui est indiquée comme argument optionnel. En d'autres termes, dans ce cas, 
this est extrait du paramètre 
.call() , par conséquent, l'appel à 
obj.getThis2.call(a) renvoie l'objet 
a .
Utilisation de la commande 
obj.getThis3 = obj.getThis.bind(obj); nous essayons de nous lier à 
this méthode, qui est une fonction de flèche. Comme nous l'avons déjà découvert, cela ne peut pas être fait. Par conséquent, les appels à 
obj.getThis3() et 
obj.getThis3.call(a) renvoient 
undefined .
Des méthodes qui sont des fonctions ordinaires peuvent être attachées à 
this , donc 
obj.getThis4() , comme prévu, renvoie 
obj . Un appel à 
obj.getThis4.call(a) renvoie 
obj et non, comme vous pouvez vous y attendre, 
a . Le fait est qu'avant d' 
obj.getThis4 = obj.getThis2.bind(obj); cette commande, nous l'avons déjà lié avec la commande 
obj.getThis4 = obj.getThis2.bind(obj); . Par conséquent, lors de l'exécution de 
obj.getThis4.call(a) , l'état de la méthode dans laquelle il se trouvait après la prise en compte de la première liaison est pris en compte.
Utiliser cela en classe
Voici la deuxième version de notre jeu - la même tâche, mais maintenant basée sur les classes. Ici, nous utilisons la syntaxe pour déclarer les champs de classe publique (pour le moment, la 
proposition de cette syntaxe est au troisième stade d'approbation, elle est disponible par défaut dans Chrome, vous pouvez l'utiliser avec 
@babel/plugin-proposal-class-properties ).
 class Obj { getThis = () => this getThis2 () {   return this; } } const obj2 = new Obj(); obj2.getThis3 = obj2.getThis.bind(obj2); obj2.getThis4 = obj2.getThis2.bind(obj2); const answers2 = [ obj2.getThis(), obj2.getThis.call(a), obj2.getThis2(), obj2.getThis2.call(a), obj2.getThis3(), obj2.getThis3.call(a), obj2.getThis4(), obj2.getThis4.call(a) ]; 
Avant de continuer à lire, pensez au code et notez votre vision de ce qui va tomber dans le tableau de 
answers2 .
Vous avez terminé?
Ici, tous les appels de méthode, à l'exception de 
obj2.getThis2.call(a) , 
obj2.getThis2.call(a) une référence à l'instance de l'objet. Le même appel renverra l'objet 
a . Les fonctions fléchées tirent toujours 
this de la portée lexicale. La différence entre cet exemple et le précédent est la différence dans la portée d'où 
this est tiré.
À savoir, nous travaillons ici avec les propriétés de classe, qui déterminent le comportement de ce code.
Le fait est que lors de la préparation du code pour l'exécution, les valeurs sont écrites dans les propriétés des classes comme ceci:
 class Obj { constructor() {   this.getThis = () => this; } ... 
En d'autres termes, il s'avère que la fonction flèche est déclarée dans le contexte de la fonction constructeur. Puisque nous travaillons avec une classe, la seule façon de l'instancier est d'utiliser le 
new mot-clé (si vous oubliez ce mot-clé, un message d'erreur sera affiché).
Les tâches les plus importantes résolues par le 
new mot clé sont de créer une nouvelle instance de l'objet et de la lier au constructeur. Cette fonctionnalité, compte tenu de ce dont nous avons déjà parlé dans la section précédente, devrait vous aider à comprendre ce qui se passe.
Résumé
Avez-vous terminé les tâches décrites dans cet article? Une bonne compréhension du comportement de 
this mot clé en JavaScript vous fera gagner une tonne de temps lors du débogage, lors de la recherche de raisons non évidentes d'erreurs obscures. Si vous avez répondu incorrectement à certaines des questions, cela signifie qu'il vous sera utile de vous entraîner.
Testez l'exemple de code, puis réessayez, etc., jusqu'à ce que vous puissiez répondre correctement à toutes les questions. Après avoir compris vous-même, trouvez quelqu'un prêt à vous écouter et dites-lui pourquoi les méthodes des tâches renvoient exactement ce qu'elles renvoient.
Si tout cela vous semble plus compliqué que prévu, sachez que vous n'êtes pas seul dans ce domaine. J'ai testé pas mal de développeurs pour connaître les fonctionnalités de 
this , et je pense qu'un seul d'entre eux était absolument précis dans toutes leurs réponses.
Ce sous-système du langage, qui au tout début ressemblait à une recherche dynamique de méthodes pouvant être influencées à l'aide de 
.call() , 
.bind() ou 
.apply() , a commencé à paraître beaucoup plus compliqué après l'apparition des fonctions fléchées et des classes.
Apparemment, il sera utile de noter les principales caractéristiques des classes et des fonctions fléchées en termes d'utilisation. N'oubliez pas que les fonctions fléchées utilisent toujours 
this partir de leur portée lexicale, et le 
this dans les classes est en fait lié à la fonction constructeur de la classe. Et si jamais vous sentez que vous ne savez pas exactement à quoi 
this renvoie, utilisez le débogueur pour vérifier vos hypothèses à ce sujet.
N'oubliez pas que vous pouvez faire beaucoup de choses en JavaScript sans utiliser 
this dans votre code. L'expérience me dit que presque tout code JS peut être réécrit sous la forme de fonctions pures qui acceptent tous les arguments avec lesquels il travaille, sous la forme d'une liste de paramètres explicitement spécifiée ( 
this peut être interprété comme un paramètre implicitement spécifié avec un état mutable). La logique contenue dans les fonctions pures est déterministe, ce qui améliore leur testabilité. De telles fonctions n'ont pas d'effets secondaires, ce qui signifie que lorsque vous travaillez avec elles, contrairement à la manipulation, il est peu probable que vous «cassiez» quoi que ce soit en dehors. Chaque fois que vous changez 
this , vous êtes confronté à un problème potentiel, à savoir que quelque chose qui en dépend peut cesser de fonctionner correctement.
Malgré ce qui précède, il convient de noter qu'il s'agit d'un concept utile. Par exemple, elle peut être appliquée afin d'organiser le partage d'une certaine méthode par une multitude d'objets. Même dans la programmation fonctionnelle, 
this peut être utile pour appeler d'autres méthodes d'un objet à partir d'une méthode, ce qui vous permet de créer quelque chose de nouveau basé sur des constructions existantes.

