J'ai remarqué qu'il ne semble pas y avoir d'explication claire de ce que la this
mot-clé et comment il est correctement (et incorrectement) utilisé en JavaScript sur le site Stack Overflow.
J'ai été témoin d'un comportement très étrange avec cela et je n'ai pas compris pourquoi cela s'est produit.
Comment this
fonctionne et quand doit-il être utilisé?
javascript
this
Maxim Gershkovich
la source
la source
this
peter.michaux.ca/articles/javascript-widgets-without-thisthis
mot - clé: rainsoft.io/gentle-explanation-of-this-in-javascriptRéponses:
Je recommande de lire d'abord l' article Scope de Mike West en JavaScript ( miroir ). C'est une excellente introduction conviviale aux concepts de
this
et aux chaînes de portée en JavaScript.Une fois que vous commencez à vous y habituer
this
, les règles sont en fait assez simples. La norme ECMAScript 5.1 définitthis
:ThisBinding est quelque chose que l'interpréteur JavaScript maintient pendant qu'il évalue le code JavaScript, comme un registre CPU spécial qui contient une référence à un objet. L'interpréteur met à jour ThisBinding chaque fois que vous établissez un contexte d'exécution dans l'un des trois cas différents uniquement:
1. Contexte d'exécution global initial
C'est le cas du code JavaScript évalué au niveau supérieur, par exemple lorsqu'il est directement à l'intérieur d'un
<script>
:Lors de l'évaluation du code dans le contexte d'exécution global initial, ThisBinding est défini sur l'objet global
window
( §10.4.1.1 ).Saisie du code d'évaluation
… Par un appel direct à
eval()
ThisBinding reste inchangé; c'est la même valeur que ThisBinding du contexte d'exécution appelant ( §10.4.2 (2) (a)).…
eval()
Sinon par un appel direct à ThisBinding est défini sur l'objet global comme s'il s'exécutait dans le contexte d'exécution global initial ( §10.4.2 (1)).
Le §15.1.2.1.1 définit ce qu'est un appel direct
eval()
. Fondamentalement,eval(...)
est un appel direct alors que quelque chose comme(0, eval)(...)
ouvar indirectEval = eval; indirectEval(...);
est un appel indirect àeval()
. Voir la réponse de chuckj à (1, eval) ('ceci') vs eval ('ceci') en JavaScript? et ECMA-262-5 de Dmitry Soshnikov en détail. Chapitre 2. Mode strict. pour savoir quand vous pourriez utiliser uneval()
appel indirect .Saisie du code de fonction
Cela se produit lors de l'appel d'une fonction. Si une fonction est appelée sur un objet, comme dans
obj.myMethod()
ou l'équivalentobj["myMethod"]()
, ThisBinding est défini sur l'objet (obj
dans l'exemple; §13.2.1 ). Dans la plupart des autres cas, ThisBinding est défini sur l'objet global ( §10.4.3 ).La raison de l'écriture «dans la plupart des autres cas» est qu'il existe huit fonctions intégrées ECMAScript 5 qui permettent de spécifier ThisBinding dans la liste des arguments. Ces fonctions spéciales prennent ce qu'on appelle
thisArg
ce qui devient ThisBinding lors de l'appel de la fonction ( §10.4.3 ).Ces fonctions intégrées spéciales sont:
Function.prototype.apply( thisArg, argArray )
Function.prototype.call( thisArg [ , arg1 [ , arg2, ... ] ] )
Function.prototype.bind( thisArg [ , arg1 [ , arg2, ... ] ] )
Array.prototype.every( callbackfn [ , thisArg ] )
Array.prototype.some( callbackfn [ , thisArg ] )
Array.prototype.forEach( callbackfn [ , thisArg ] )
Array.prototype.map( callbackfn [ , thisArg ] )
Array.prototype.filter( callbackfn [ , thisArg ] )
Dans le cas des
Function.prototype
fonctions, elles sont appelées sur un objet fonction, mais plutôt que de définir ThisBinding sur l'objet fonction, ThisBinding est défini surthisArg
.Dans le cas des
Array.prototype
fonctions, la donnéecallbackfn
est appelée dans un contexte d'exécution où ThisBinding est défini surthisArg
si fourni; sinon, à l'objet global.Ce sont les règles du JavaScript simple. Lorsque vous commencez à utiliser des bibliothèques JavaScript (par exemple jQuery), vous pouvez constater que certaines fonctions de bibliothèque manipulent la valeur de
this
. Les développeurs de ces bibliothèques JavaScript le font car il a tendance à prendre en charge les cas d'utilisation les plus courants, et les utilisateurs de la bibliothèque trouvent généralement ce comportement plus pratique. Lorsque vous transmettez des fonctions de rappel faisant référencethis
à des fonctions de bibliothèque, vous devez vous référer à la documentation pour toutes les garanties sur la valeur dethis
lorsque la fonction est appelée.Si vous vous demandez comment une bibliothèque JavaScript manipule la valeur de
this
, la bibliothèque utilise simplement l'une des fonctions JavaScript intégrées acceptant athisArg
. Vous pouvez également écrire votre propre fonction en utilisant une fonction de rappel etthisArg
:Il y a un cas particulier que je n'ai pas encore mentionné. Lors de la construction d'un nouvel objet via l'
new
opérateur, l'interpréteur JavaScript crée un nouvel objet vide, définit certaines propriétés internes, puis appelle la fonction constructeur sur le nouvel objet. Ainsi, lorsqu'une fonction est appelée dans un contexte constructeur, la valeur dethis
est le nouvel objet créé par l'interpréteur:Fonctions fléchées
Les fonctions fléchées (introduites dans ECMA6) modifient la portée de
this
. Voir la question canonique existante, fonction flèche vs déclaration / expressions de fonction: sont-elles équivalentes / échangeables? pour plus d'informations. Mais en bref:Juste pour le plaisir, testez votre compréhension avec quelques exemples
Pour révéler les réponses, passez la souris sur les cases gris clair.
Quelle est la valeur de
this
la ligne marquée? Pourquoi?Quelle est la valeur de
this
la ligne marquée lors de l'obj.staticFunction()
exécution? Pourquoi?Quelle est la valeur de
this
la ligne marquée? Pourquoi?Quelle est la valeur de
this
la ligne marquée? Pourquoi?Quelle est la valeur de
this
la ligne marquée? Pourquoi?la source
setTimeout
exemple a unthis
dewindow(global)
.Le
this
mot clé se comporte différemment en JavaScript par rapport à d'autres langues. Dans les langages orientés objet, lethis
mot - clé fait référence à l'instance actuelle de la classe. En JavaScript, la valeur dethis
est déterminée par le contexte d'invocation de la fonction (context.function()
) et l'endroit où elle est appelée.1. Lorsqu'il est utilisé dans un contexte mondial
Lorsque vous utilisez
this
dans un contexte global, il est lié à un objet global (window
dans le navigateur)Lorsque vous utilisez à l'
this
intérieur d'une fonction définie dans le contexte global,this
est toujours lié à un objet global car la fonction est en fait une méthode de contexte global.Ci
f1
- dessus est faite une méthode d'objet global. Ainsi, nous pouvons également l'appeler sur l'window
objet comme suit:2. Lorsqu'il est utilisé à l'intérieur de la méthode objet
Lorsque vous utilisez un
this
mot clé dans une méthode objet,this
est lié à l'objet englobant "immédiat".Ci-dessus, j'ai mis le mot immédiat entre guillemets. Cela signifie que si vous imbriquez l'objet dans un autre objet, il
this
est lié au parent immédiat.Même si vous ajoutez explicitement une fonction à l'objet en tant que méthode, elle suit toujours les règles ci-dessus, c'est-à-dire
this
pointe vers l'objet parent immédiat.3. Lors de l'appel de la fonction sans contexte
Lorsque vous utilisez une
this
fonction interne invoquée sans aucun contexte (c'est-à-dire pas sur un objet), elle est liée à l'objet global (window
dans le navigateur) (même si la fonction est définie à l'intérieur de l'objet).Tout essayer avec des fonctions
Nous pouvons également essayer les points ci-dessus avec des fonctions. Il existe cependant quelques différences.
this
. pour les préciser.new
opérateur.Ci-dessous, j'ai essayé toutes les choses que nous avons faites avec Object et
this
ci - dessus, mais en créant d'abord une fonction au lieu d'écrire directement un objet.4. Lorsqu'il est utilisé dans la fonction constructeur .
Lorsque la fonction est utilisée comme constructeur (c'est-à-dire lorsqu'elle est appelée avec un
new
mot-clé), lethis
corps de la fonction interne pointe vers le nouvel objet en cours de construction.5. Lorsqu'il est utilisé à l'intérieur d'une fonction définie sur la chaîne du prototype
Si la méthode se trouve sur la chaîne prototype d'un objet, à l'
this
intérieur d'une telle méthode fait référence à l'objet auquel la méthode a été appelée, comme si la méthode était définie sur l'objet.6. Fonctions internes call (), apply () et bind ()
Function.prototype
.this
qui sera utilisée lors de l'exécution de la fonction. Ils prennent également tous les paramètres à transmettre à la fonction d'origine lors de son appel.fun.apply(obj1 [, argsArray])
Définitobj1
comme la valeur dethis
insidefun()
et appellefun()
les éléments de passage deargsArray
comme arguments.fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])
- Définitobj1
comme la valeur dethis
insidefun()
et les appelsfun()
passantarg1, arg2, arg3, ...
comme arguments.fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])
- Renvoie la référence à la fonctionfun
avecthis
fun intérieur lié àobj1
et paramètres defun
lié aux paramètres spécifiésarg1, arg2, arg3,...
.apply
,call
etbind
doit être devenue apparente.apply
permet de spécifier les arguments pour fonctionner comme un objet de type tableau, c'est-à-dire un objet avec unelength
propriété numérique et des propriétés entières non négatives correspondantes. Alors quecall
permet de spécifier directement les arguments de la fonction. Les deuxapply
etcall
invoque immédiatement la fonction dans le contexte spécifié et avec les arguments spécifiés. En revanche,bind
renvoie simplement la fonction liée à lathis
valeur spécifiée et aux arguments. Nous pouvons capturer la référence à cette fonction retournée en l'affectant à une variable et plus tard, nous pouvons l'appeler à tout moment.7.
this
gestionnaires d'événements internesthis
la fonction de gestion d'événements directement à l'intérieur fait référence à l'élément correspondant. Une telle affectation directe de fonction peut être effectuée en utilisant laaddeventListener
méthode ou par les méthodes d'enregistrement d'événements traditionnelles commeonclick
.this
directement à l'intérieur de la propriété d'événement (comme<button onclick="...this..." >
) de l'élément, il fait référence à l'élément.this
indirecte via l'autre fonction appelée à l'intérieur de la fonction de gestion des événements ou de la propriété d'événement se résout en l'objet globalwindow
.attachEvent
. Au lieu d'affecter la fonction au gestionnaire d'événements (et donc de créer la méthode de fonction de l'élément), il appelle la fonction sur l'événement (l'appelle effectivement dans le contexte global).Je recommande de mieux essayer ceci dans JSFiddle .
8.
this
dans la fonction flèche ES6Dans une fonction flèche,
this
se comportera comme des variables communes: elle sera héritée de sa portée lexicale. La fonctionthis
, où la fonction flèche est définie, sera celle de la fonction flèchethis
.Donc, c'est le même comportement que:
Voir le code suivant:
la source
this
n'est pas définie par l'appel. Étant donné que le code n'est pas en mode strict, la valeur dethis
doit toujours être un objet, il est donc défini par défaut sur l'objet global. Et en fait, c'est pourquoi j'ai pensé que nous pouvions appeler directementwindow.f1()
, de sorte que les moyensf1()
sont déjà attachés à l'window
objet, je veux dire avant l'invocation. Suis-je en train de me tromper?window.fn
, ce qui n'est pas le cas. cela signifie par défaut l'objet global car aucune référence de base n'a été utilisée dans l'appel, pas à cause de l'endroit où la fonction est définie (donc cela est toujours défini par la façon dont la fonction a été appelée). Si vous l'appelez explicitement à l'aidewindow.fn
, vous définissez cette option sur fenêtre . Même résultat, façon différente de procéder. :-)Javascript
this
Appel de fonction simple
Considérez la fonction suivante:
Notez que nous l'exécutons en mode normal, c'est-à-dire que le mode strict n'est pas utilisé.
Lors de l'exécution dans un navigateur, la valeur de
this
serait enregistrée souswindow
. C'est parce quewindow
c'est la variable globale dans la portée d'un navigateur Web.Si vous exécutez ce même morceau de code dans un environnement comme node.js,
this
ferait référence à la variable globale dans votre application.Maintenant, si nous l'exécutons en mode strict en ajoutant l'instruction
"use strict";
au début de la déclaration de fonction,this
ne ferait plus référence à la variable globale dans aucun des environnements. Ceci est fait pour éviter les confusions en mode strict.this
serait, dans ce cas, simplement se connecterundefined
, car c'est ce qu'il est, il n'est pas défini.Dans les cas suivants, nous verrions comment manipuler la valeur de
this
.Appel d'une fonction sur un objet
il y a différentes facons de faire cela. Si vous avez appelé des méthodes natives en Javascript comme
forEach
etslice
, vous devez déjà savoir que lathis
variable dans ce cas fait référence à celleObject
sur laquelle vous avez appelé cette fonction (notez qu'en javascript, à peu près tout est unObject
, y comprisArray
s etFunction
s). Prenons l'exemple du code suivant.Si un
Object
contient une propriété qui contient unFunction
, la propriété est appelée une méthode. Cette méthode, lorsqu'elle est appelée, aura toujours sathis
variable définie sur la valeur à laquelleObject
elle est associée. Cela est vrai pour les modes stricts et non stricts.Notez que si une méthode est stockée (ou plutôt copiée) dans une autre variable, la référence à
this
n'est plus conservée dans la nouvelle variable. Par exemple:Considérant un scénario plus couramment pratique:
Le
new
mot cléConsidérons une fonction constructeur en Javascript:
Comment cela marche-t-il? Voyons ce qui se passe lorsque nous utilisons le
new
mot - clé.new
mot clé initialiserait immédiatement unObject
typePerson
.Object
a son constructeur réglé surPerson
. Notez également que celatypeof awal
ne reviendraObject
que.Object
verrait attribuer le prototype dePerson.prototype
. Cela signifie que toute méthode ou propriété duPerson
prototype serait disponible pour toutes les instances dePerson
, y comprisawal
.Person
elle-même est maintenant invoquée;this
étant une référence à l'objet nouvellement construitawal
.Assez simple, hein?
Notez que la spécification ECMAScript officielle n'indique nulle part que ces types de fonctions sont des
constructor
fonctions réelles . Ce ne sont que des fonctions normales etnew
peuvent être utilisées sur n'importe quelle fonction. C'est juste que nous les utilisons en tant que tels, et donc nous les appelons uniquement en tant que tels.Appeler des fonctions sur les fonctions:
call
etapply
Donc oui, puisque les
function
s le sont aussiObjects
(et en fait les variables de première classe en Javascript), même les fonctions ont des méthodes qui sont ... eh bien, les fonctions elles-mêmes.Toutes les fonctions héritent du global
Function
, et deux de ses nombreuses méthodes sontcall
etapply
, et les deux peuvent être utilisées pour manipuler la valeur dethis
dans la fonction sur laquelle elles sont appelées.Ceci est un exemple typique d'utilisation
call
. Il prend essentiellement le premier paramètre et définitthis
la fonctionfoo
comme référencethisArg
. Tous les autres paramètres passés àcall
sont passés à la fonctionfoo
comme arguments.Le code ci-dessus se connectera donc
{myObj: "is cool"}, [1, 2, 3]
à la console. Très belle façon de changer la valeur dethis
n'importe quelle fonction.apply
équivaut presque àcall
accepter qu'il ne prend que deux paramètres:thisArg
et un tableau qui contient les arguments à passer à la fonction. Ainsi, l'call
appel ci - dessus peut être traduitapply
comme ceci:Notez que
call
etapply
peut remplacer la valeur de l'this
invocation de la méthode set by dot dont nous avons parlé dans la deuxième puce. Assez simple :)Présentation ....
bind
!bind
est un frère decall
etapply
. C'est également une méthode héritée par toutes les fonctions duFunction
constructeur global en Javascript. La différence entrebind
etcall
/apply
est que les deuxcall
etapply
invoqueront réellement la fonction.bind
, d'autre part, retourne une nouvelle fonction avec lethisArg
etarguments
préréglé. Prenons un exemple pour mieux comprendre ceci:Voyez la différence entre les trois? C'est subtil, mais ils sont utilisés différemment. Comme
call
etapply
,bind
outrepassera également la valeur dethis
set by invocation méthode dot.Notez également qu'aucune de ces trois fonctions ne modifie la fonction d'origine.
call
etapply
retournerait la valeur des fonctions fraîchement construites tandis quebind
retournera la fonction fraîchement construite elle-même, prête à être appelée.Des trucs supplémentaires, copiez ceci
Parfois, vous n'aimez pas le fait que les
this
modifications avec la portée, en particulier la portée imbriquée. Jetez un œil à l'exemple suivant.Dans le code ci-dessus, nous voyons que la valeur de a
this
changé avec la portée imbriquée, mais nous voulions la valeur dethis
la portée d'origine. Nous avons donc « copié »this
àthat
et utilisé la copie au lieu dethis
. Intelligent, hein?Indice:
this
par défaut?new
mot-clé?this
aveccall
etapply
?bind
.this
pour résoudre les problèmes de portée imbriquée.la source
"ceci" est une question de portée. Chaque fonction a sa propre portée, et puisque tout dans JS est un objet, même une fonction peut stocker certaines valeurs en elle-même en utilisant "ceci". La POO 101 enseigne que "ceci" ne s'applique qu'aux instances d'un objet. Par conséquent, chaque fois qu'une fonction s'exécute, une nouvelle "instance" de cette fonction a une nouvelle signification de "ceci".
La plupart des gens sont confus lorsqu'ils essaient d'utiliser "ceci" dans des fonctions de fermeture anonymes comme:
Donc ici, à l'intérieur de chaque (), "ceci" ne contient pas la "valeur" à laquelle vous vous attendez (de
Au dessus de). Donc, pour surmonter ce problème (sans jeu de mots), un développeur pourrait:Essaye le; vous commencerez à aimer ce schéma de programmation
la source
this
mot-clé n'a rien à voir avec la portée. En outre, il a également une signification dans les fonctions qui ne sont pas des propriétés d'objets.this
n'est pas TOUT sur la portée. Tout dépend du contexte d'exécution, ce qui n'est pas la même chose que la portée. JavaScript a une portée lexicale (ce qui signifie que la portée est déterminée par l'emplacement du code), maisthis
est déterminée par la façon dont la fonction qui le contient est invoquée - et non par l'emplacement de cette fonction.Depuis ce fil a augmenté, j'ai compilé quelques points pour les lecteurs nouveaux sur le
this
sujet.Comment la valeur de est-elle
this
déterminée?Nous utilisons cela de la même manière que nous utilisons les pronoms dans les langues naturelles comme l'anglais: "John court vite parce qu'il essaie d'attraper le train." Au lieu de cela, nous aurions pu écrire «… John essaie de prendre le train».
this
ne reçoit pas de valeur tant qu'un objet n'appelle pas la fonction où il est défini. Dans la portée globale, toutes les variables et fonctions globales sont définies sur l'window
objet. Par conséquent,this
dans une fonction globale fait référence à (et a la valeur de) l'window
objet global .Lorsque
use strict
,this
dans les fonctions globales et anonymes qui ne sont liées à aucun objet, contient une valeur deundefined
.Le
this
mot-clé est le plus mal compris lorsque: 1) nous empruntons une méthode qui utilisethis
, 2) nous attribuons une méthode qui utilisethis
à une variable, 3) une fonction qui utilisethis
est passée en tant que fonction de rappel, et 4)this
est utilisée à l'intérieur d'une fermeture - une fonction intérieure. (2)Ce qui nous réserve l'avenir
Définies dans ECMA Script 6 , les fonctions fléchées adoptent la
this
liaison de l'étendue englobante (fonction ou globale).Bien que les fonctions fléchées offrent une alternative à l'utilisation
bind()
, il est important de noter qu'elles désactivent essentiellement lethis
mécanisme traditionnel au profit d'une portée lexicale plus largement comprise. (1)Références:
la source
this
en JavaScript fait toujours référence au «propriétaire» de la fonction en cours d'exécution .Si aucun propriétaire explicite n'est défini, le propriétaire le plus haut, l'objet fenêtre, est référencé.
Donc si je le faisais
element.onclick = someKindOfFunction;
this
ferait référence à l'objet élément. Mais attention, beaucoup de gens font cette erreur.<element onclick="someKindOfFunction()">
Dans ce dernier cas, vous vous contentez de référencer la fonction, pas de la remettre à l'élément. Par conséquent,
this
fera référence à l'objet fenêtre.la source
Chaque contexte d'exécution en javascript a un paramètre this défini par:
eval
Vous pouvez définir la valeur de ceci en utilisant
func.call
,func.apply
oufunc.bind
.Par défaut, et ce qui déroute la plupart des débutants, lorsqu'un écouteur est appelé après qu'un événement est déclenché sur un élément DOM, la valeur this de la fonction est l'élément DOM.
jQuery rend cela trivial à changer avec jQuery.proxy.
la source
this
dans Javascript, c'est que ce n'est pas une propriété intrinsèque de la fonction elle-même, mais plutôt un artefact de la façon dont la fonction est invoquée.func.call
,func.bind
etc. - Sushilthis
ne fait pas référence à l'étendue d'une fonction.this
fera référence à un objet spécifique (ou éventuellementundefined
), qui, comme vous l'avez dit, peut être modifié à l'aide de.call()
ou.apply()
. La portée d' une fonction est (essentiellement, lorsqu'elle est simplifiée) à quelles variables elle a accès, et cela dépend entièrement de l'endroit où la fonction est déclarée et ne peut pas être modifiée.this
et la portée n'a rien à voir avec ES5 et avant (par exemple, lorsque cette réponse a été écrite). Dans ES2015 (aka ES6),this
et la portée sont liées d' une manière assez minimale aux fonctions de flèche wrt (la fonctionthis
dans une flèche est héritée de sa portée englobante), maisthis
ne fait jamais référence à une portée.Voici une bonne source de
this
inJavaScript
.Voici le résumé:
ce mondial
Dans un navigateur, à la portée globale,
this
est l'window
objetEn
node
utilisant le repl,this
est l'espace de noms supérieur. Vous pouvez vous y référer commeglobal
.Lors de l'
node
exécution à partir d'un script,this
la portée globale commence comme un objet vide. Ce n'est pas la même chose queglobal
faire fonctionner cela
Sauf dans le cas des gestionnaires d'événements DOM ou lorsqu'un a
thisArg
est fourni (voir plus bas), à la fois dans le nœud et dans un navigateur utilisantthis
dans une fonction qui n'est pas appelée avec desnew
références la portée globale…Si vous utilisez
use strict;
, auquel casthis
seraundefined
Si vous appelez une fonction avec
new
lethis
sera un nouveau contexte, il ne référencera pas le globalthis
.Les fonctions que vous créez deviennent des objets de fonction. Ils obtiennent automatiquement une
prototype
propriété spéciale , à laquelle vous pouvez attribuer des valeurs. Lorsque vous créez une instance en appelant votre fonction avec,new
vous avez accès aux valeurs que vous avez attribuées à laprototype
propriété. Vous accédez à ces valeurs à l'aide dethis
.C'est généralement une erreur d'attribuer des tableaux ou des objets sur le
prototype
. Si vous voulez que les instances aient chacune leurs propres tableaux, créez-les dans la fonction, pas dans le prototype.Vous pouvez utiliser
this
dans n'importe quelle fonction d'un objet pour faire référence à d'autres propriétés de cet objet. Ce n'est pas la même chose qu'une instance créée avecnew
.Dans un gestionnaire d'événements DOM HTML,
this
est toujours une référence à l'élément DOM auquel l'événement a été attachéSauf si vous
bind
le contexteÀ l'intérieur des attributs HTML dans lesquels vous pouvez mettre JavaScript, se
this
trouve une référence à l'élément.Vous pouvez utiliser
eval
pour accéderthis
.Vous pouvez utiliser
with
pour ajouterthis
à la portée actuelle pour lire et écrire sur des valeursthis
sans faire référencethis
explicitement.la jQuery aura à de nombreux endroits fait
this
référence à un élément DOM.la source
Daniel, super explication! Quelques mots sur cela et une bonne liste de
this
pointeurs de contexte d'exécution en cas de gestionnaires d'événements.En deux mots,
this
en JavaScript pointe l'objet à partir duquel (ou à partir de quel contexte d'exécution) la fonction actuelle a été exécutée et elle est toujours en lecture seule, vous ne pouvez pas la définir de toute façon (une telle tentative se terminera par 'Invalid left-hand côté dans le message d'affectation.Pour les gestionnaires d'événements: les gestionnaires d'événements en ligne, tels que
<element onclick="foo">
, remplacent tous les autres gestionnaires attachés plus tôt et avant, alors soyez prudent et il vaut mieux éviter la délégation d'événements en ligne. Et merci à Zara Alaverdyan qui m'a inspiré cette liste d'exemples à travers un débat dissident :)el.onclick = foo; // in the foo - obj
el.onclick = function () {this.style.color = '#fff';} // obj
el.onclick = function() {doSomething();} // In the doSomething - Window
el.addEventListener('click',foo,false) // in the foo - obj
el.attachEvent('onclick, function () { // this }') // window, all the compliance to IE :)
<button onclick="this.style.color = '#fff';"> // obj
<button onclick="foo"> // In the foo - window, but you can <button onclick="foo(this)">
la source
Il y a beaucoup de confusion quant à la façon dont "ce" mot clé est interprété en JavaScript. Espérons que cet article mettra tous ceux au repos une fois pour toutes. Et beaucoup plus. Veuillez lire attentivement l'intégralité de l'article. Soyez averti que cet article est long.
Quel que soit le contexte dans lequel il est utilisé, "this" fait toujours référence à "l'objet courant" en Javascript. Cependant, ce qu'est "l'objet courant" diffère selon le contexte . Le contexte peut être exactement 1 des 6 suivants:
Ce qui suit décrit chacun de ces contextes un par un:
Contexte global (c'est-à-dire en dehors de toutes les fonctions):
En dehors de toutes les fonctions (c'est-à-dire dans un contexte global), "l'objet courant" (et donc la valeur de "this" ) est toujours l' objet "window" pour les navigateurs.
Appel direct "Fonction non liée" interne :
Dans un appel direct à «fonction non liée», l'objet qui a appelé l'appel de fonction devient «l'objet actuel» (et donc la valeur de «ceci» ). Si une fonction est appelée sans objet courant explicite , l' objet courant est soit l' objet "fenêtre" (pour le mode non strict) soit indéfini (pour le mode strict). Toute fonction (ou variable) définie dans le contexte global devient automatiquement une propriété de l'objet "fenêtre" . Par exemple, supposons que la fonction soit définie dans le contexte global comme
il devient la propriété de l'objet window, comme si vous l'aviez défini comme
En "mode non strict", appeler / appeler cette fonction directement via "UserDefinedFunction ()" l'appellera / appellera automatiquement comme "window.UserDefinedFunction ()" faisant "window" comme "objet courant" (et donc la valeur de " ceci " ) dans " UserDefinedFunction ". L' invocation de cette fonction en" Mode non strict "entraînera ce qui suit
En « Mode Strict », appel / Invoquer la fonction directement par « UserDefinedFunction () » sera « pas » appeler automatiquement / Invoke comme « window.UserDefinedFunction () » .Hence le « objet courant » (et la valeur de « cette » ) dans "UserDefinedFunction" ne doit pas être défini . L'appel de cette fonction en "mode strict" se traduira par ce qui suit
Cependant, son invocation explicite à l'aide d'un objet window se traduira par ce qui suit
Voyons un autre exemple. Veuillez regarder le code suivant
Dans l'exemple ci-dessus, nous voyons que lorsque "UserDefinedFunction" a été invoqué via o1 , "this" prend la valeur de o1 et la valeur de ses propriétés "a" et "b" s'affichent. La valeur de "c" et "d" était indiquée comme non définie car o1 ne définit pas ces propriétés
De même lorsque "UserDefinedFunction" été invoqué via o2 , "this" prend la valeur de o2 et la valeur de ses propriétés "c" et "d" s'affichent. La valeur de "a" et "b" était indiquée comme non définie comme o2 le fait pas définir ces propriétés.
Dans la fonction indirecte "Fonction non liée", appelez via functionName.call et functionName.apply :
Lorsqu'un "fonction non liée" est appelée via functionName.call ou functionName.apply , l ' "objet actuel" (et donc la valeur de "this" ) est défini sur la valeur de "this" paramètre (premier paramètre) passé pour appeler / appliquer . Le code suivant illustre la même chose.
Le code ci-dessus montre clairement que la valeur «this» pour toute «fonction NON liée» peut être modifiée par appel / application . De plus, si le paramètre "this" n'est pas explicitement transmis à call / apply , "objet courant" (et donc la valeur de "this") est défini sur "window" en mode non strict et "undefined" en mode strict.
A l'intérieur de la fonction "Bound Function" (c'est-à-dire une fonction qui a été liée par l'appel functionName.bind ):
Une fonction liée est une fonction dont "cette" valeur a été fixée. Le code suivant montre comment "ceci" fonctionne en cas de fonction liée
Comme indiqué dans le code ci-dessus, "cette" valeur pour toute "fonction liée" NE PEUT PAS être modifiée par appel / application . De plus, si le "this" paramètre n'est pas explicitement transmis pour la liaison, "object courant" (et donc la valeur de "this" ) est défini sur "window" en mode Non strict et "undefined" en mode strict. Encore une chose. La liaison d'une fonction déjà liée ne modifie pas la valeur de "this" . Il reste défini comme la valeur définie par la première fonction de liaison.
Alors que la création d'objets à travers "nouveau" :
À l'intérieur d'une fonction constructeur, l ' "objet actuel" (et donc la valeur de "this" ) fait référence à l'objet qui est en cours de création via "new" quel que soit l'état de liaison de la fonction. Cependant, si le constructeur est une fonction liée, il doit être appelé avec un ensemble d'arguments prédéfini comme défini pour la fonction liée.
Dans le gestionnaire d'événements Inline DOM :
Veuillez consulter l'extrait HTML suivant
Le "ceci" dans les exemples ci-dessus fait respectivement référence à l'élément "bouton" et à l'élément "div".
Dans le premier exemple, la couleur de police du bouton doit être définie sur blanc lorsque vous cliquez dessus.
Dans le deuxième exemple, lorsque l' élément "div" est cliqué, il doit appeler la fonction OnDivClick avec son deuxième paramètre référençant l'élément div cliqué. Cependant, la valeur de "this" dans OnDivClick NE DOIT PAS faire référence à l' élément div cliqué . Il doit être défini comme «objet fenêtre» ou «non défini» dans les modes non strict et strict respectivement (si OnDivClick est une fonction non liée ) ou défini sur une valeur liée prédéfinie (si OnDivClick est une fonction liée )
Ce qui suit résume l'intégralité de l'article
Dans le contexte global, "this" fait toujours référence à l' objet "window"
Chaque fois qu'une fonction est invoquée, elle est invoquée dans le contexte d'un objet ( "objet courant" ). Si l' objet actuel n'est pas explicitement fourni, l' objet actuel est "l'objet fenêtre" en mode NON strict et "non défini" en mode strict par défaut.
La valeur de "this" dans une fonction Non Bound est la référence à l'objet dans le contexte duquel la fonction est invoquée ( "objet courant" )
La valeur de "ceci" dans une fonction non liée peut être remplacée par appel et appliquer des méthodes de la fonction.
La valeur de "this" est fixée pour une fonction Bound et ne peut pas être remplacée par l' appel et l' application méthodes de la fonction.
La fonction de liaison et déjà liée ne change pas la valeur de "this". Il reste défini comme la valeur définie par la première fonction de liaison.
La valeur de "this" dans un constructeur est l'objet qui est créé et initialisé
La valeur de "this" dans un gestionnaire d'événements DOM en ligne fait référence à l'élément pour lequel le gestionnaire d'événements est donné.
la source
L'article probablement le plus détaillé et le plus complet
this
est le suivant:Explication douce de «ce» mot-clé en JavaScript
L'idée derrière
this
est de comprendre que les types d'invocation de fonctions ont une importance significative sur la définition de lathis
valeur.Lorsque vous avez des problèmes d'identification
this
, ne vous demandez pas:mais ne demandez-vous:
Pour une fonction flèche (cas particulier de transparence du contexte), demandez-vous:
Cet état d'esprit est correct lorsqu'il s'agit de
this
et vous évitera des maux de tête.la source
this
mot clé.C'est la meilleure explication que je l' ai vu: Comprendre JavaScripts ce avec clarté
Il y a quatre scénarios où cela peut être déroutant:
Il donne des exemples de code, des explications et des solutions, ce qui m'a semblé très utile.
la source
En termes pseudoclassiques, la façon dont de nombreuses conférences enseignent le mot-clé «this» est comme un objet instancié par une classe ou un constructeur d'objet. Chaque fois qu'un nouvel objet est construit à partir d'une classe, imaginez que sous le capot, une instance locale d'un «ce» objet est créée et renvoyée. Je me souviens qu'il a enseigné comme ceci:
la source
this
est l'un des concepts mal compris en JavaScript car il se comporte peu différemment d'un endroit à l'autre. Sethis
réfère simplement au "propriétaire" de la fonction que nous exécutons actuellement .this
aide à obtenir l'objet actuel (aka contexte d'exécution) avec lequel nous travaillons. Si vous comprenez dans quel objet la fonction en cours est CHAISE, vous pouvez comprendre ce que facilement en coursthis
est -Ci-dessus, nous créons 3 variables avec le même nom 'val'. Un dans le contexte global, un à l'intérieur de obj et l'autre à l'intérieur de la méthode d'obj. JavaScript résout les identifiants dans un contexte particulier en remontant la chaîne de portée du local au global.
Peu d'endroits où
this
se différencierAppel d'une méthode d'un objet
Lorsque la ligne1 est exécutée, JavaScript établit un contexte d'exécution (EC) pour l'appel de fonction, en définissant
this
l' objet référencé par ce qui précède le dernier "." . donc dans la dernière ligne, vous pouvez comprendre que cela aa()
été exécuté dans le contexte global qui est lewindow
.Avec constructeur
this
peut être utilisé pour faire référence à l'objet en cours de créationLorsque new
Person()
est exécuté, un objet entièrement nouveau est créé.Person
est appelé et sonthis
est défini pour référencer ce nouvel objet.Appel de fonction
Si nous oublions un
new
mot-clé, faitwhatIsThis
référence au contexte le plus global qu'il peut trouver (window
)Avec des gestionnaires d'événements
Si le gestionnaire d'événements est en ligne,
this
fait référence à un objet globalLors de l'ajout d'un gestionnaire d'événements via JavaScript,
this
fait référence à l'élément DOM qui a généré l'événement..apply()
.call()
et.bind()
var that = this
signifie en JavaScriptla source
La valeur de "this" dépend du "contexte" dans lequel la fonction est exécutée. Le contexte peut être n'importe quel objet ou l'objet global, c'est-à-dire une fenêtre.
La sémantique de "ceci" est donc différente des langages OOP traditionnels. Et cela pose des problèmes: 1. lorsqu'une fonction est passée à une autre variable (très probablement, un rappel); et 2. lorsqu'une fermeture est invoquée à partir d'une méthode membre d'une classe.
Dans les deux cas, il s'agit de window.
la source
Cette aide serait- elle utile? (La plus grande confusion de `` ceci '' en javascript vient du fait qu'il n'est généralement pas lié à votre objet, mais à la portée d'exécution actuelle - ce n'est peut-être pas exactement comment cela fonctionne, mais c'est toujours comme ça pour moi - voir l'article pour une explication complète)
la source
Quelques informations à ce sujet mot clé
Connectons le
this
mot-clé à la console dans la portée globale sans plus de code maisDans le mot-clé Client / Navigateur
this
est un objet global qui estwindow
et
Dans le mot de passe d' exécution Server / Node / Javascript
this
est également un objet global qui estmodule.exports
Gardez à l'esprit
exports
est juste une référence àmodule.exports
la source
cette utilisation pour Scope comme ça
la valeur de txt1 et txt est identique dans l'exemple ci-dessus $ (this) = $ ('# tbleName tbody tr') is Same
la source
J'ai une vision différente
this
des autres réponses qui, je l'espère, est utile.Une façon de regarder JavaScript est de voir qu'il n'y a qu'une seule façon d'appeler une fonction 1 . C'est
Il y a toujours une certaine valeur fournie pour
objectForThis
.Tout le reste est du sucre syntaxique pour
functionObject.call
Ainsi, tout le reste peut être décrit par la façon dont il se traduit
functionObject.call
.Si vous appelez simplement une fonction
this
est alors "l'objet global" qui dans le navigateur est la fenêtreEn d'autres termes,
a été effectivement traduit en
Notez que si vous utilisez le mode strict alors
this
seraundefined
ce qui signifie
En d'autres termes,
a été effectivement traduit en
En JavaScript, il existe des opérateurs comme
+
et-
et*
. Il y a aussi l'opérateur point qui est.
L'
.
opérateur, lorsqu'il est utilisé avec une fonction à droite et un objet à gauche, signifie effectivement "passer l'objet commethis
pour fonctionner".Exemple
En d'autres termes se
bar.foo()
traduit parconst temp = bar.foo; temp.call(bar);
Notez que la façon dont la fonction a été créée n'a pas d'importance (principalement ...). Tous ces éléments produiront les mêmes résultats
Encore une fois, ce ne sont que du sucre syntaxique pour
Une autre ride est la chaîne prototype. Lorsque vous utilisez
a.b
JavaScript, regardez d' abord l'objet référencé directement para
pour la propriétéb
. S'ilb
n'est pas trouvé sur l'objet, JavaScript cherchera dans le prototype de l'objet à rechercherb
.Il existe différentes façons de définir le prototype d'un objet, la plus courante en 2019 est le
class
mot - clé. Pour les besoins dethis
cela, cela n'a pas d'importance. Ce qui importe, c'est que lorsqu'il recherche dans l'objeta
une propriétéb
s'il trouve une propriétéb
sur l'objet ou dans sa chaîne de prototypes s'ilb
finit par être une fonction, les mêmes règles que ci-dessus s'appliquent. Lesb
références de fonction seront appelées en utilisant lacall
méthode et en passanta
comme objectForThis comme indiqué en haut de cette réponse.Maintenant. Imaginons que nous créons une fonction qui définit explicitement
this
avant d'appeler une autre fonction, puis appelons-la avec l'.
opérateur (point)Suite à la traduction à utiliser
call
,obj.bar()
devientconst temp = obj.bar; temp.call(obj);
. Lorsque nous entrons dans labar
fonction que nous appelonsfoo
mais que nous passons explicitement dans un autre objet pour objectForThis, donc quand nous arrivons à foo,this
c'est cet objet intérieur.C'est ce que font à la fois
bind
et les=>
fonctions. Ce sont des sucres plus syntaxiques. Ils construisent efficacement une nouvelle fonction invisible exactement commebar
ci-dessus qui définit explicitementthis
avant d'appeler la fonction spécifiée. Dans le cas où bindthis
est réglé sur ce que vous passezbind
.Notez que s'il
functionObject.bind
n'existait pas, nous pourrions faire le nôtre comme çaet nous pourrions l'appeler comme ça
Fonctions fléchées, l'
=>
opérateur est le sucre syntaxique pour la liaisonest le même que
Tout comme
bind
, une nouvelle fonction invisible est créée qui appelle la fonction donnée avec une valeur liéeobjectForThis
mais contrairement àbind
l'objet à lier, elle est implicite. C'est ce quithis
se passe quand l'=>
opérateur est utilisé.Donc, tout comme les règles ci-dessus
obj.foo()
se traduit parconst temp = obj.foo; temp.call(obj);
ce qui signifie que l'opérateur de flèche à l'intérieurfoo
se lieraobj
à une nouvelle fonction invisible et renverra cette nouvelle fonction invisible à laquelle il est affectéb
.b()
fonctionnera comme il a toujours commeb.call(window)
ou enb.call(undefined)
appelant la nouvelle fonction invisible qui afoo
créé. Cette fonction invisible ignore lethis
passé en elle et passeobj
comme objectForThis` à la fonction flèche.Le code ci-dessus se traduit par
1
apply
est une autre fonction similaire àcall
Mais à partir d'ES6 conceptuellement, vous pouvez même traduire cela en
la source
Résumé
this
Javascript:this
est déterminée par la façon dont la fonction n'est pas invoquée, où elle a été créée!this
est déterminée par l'objet qui est à gauche du point. (window
dans l'espace mondial)this
fait référence à l'élément DOM sur lequel l'événement a été appelé.new
mot - clé, la valeur dethis
fait référence à l'objet nouvellement crééthis
des fonctions:call
,apply
,bind
Exemple:
Exemples d'écouteurs d'événements:
Exemple de constructeur:
la source
Pour bien comprendre "cela", il faut comprendre le contexte, la portée et la différence entre eux.
Portée : En javascript, la portée est liée à la visibilité des variables, la portée est obtenue grâce à l'utilisation de la fonction. (En savoir plus sur la portée)
Contexte : le contexte est lié aux objets. Il fait référence à l'objet auquel appartient une fonction. Lorsque vous utilisez le mot clé JavaScript «this», il fait référence à l'objet auquel appartient la fonction. Par exemple, à l'intérieur d'une fonction, lorsque vous dites: «this.accoutNumber», vous faites référence à la propriété «accoutNumber», qui appartient à l'objet auquel appartient cette fonction.
Si l'objet «myObj» a une méthode appelée «getMyName», lorsque le mot clé JavaScript «this» est utilisé à l'intérieur de «getMyName», il fait référence à «myObj». Si la fonction «getMyName» a été exécutée dans la portée globale, «this» fait référence à l'objet window (sauf en mode strict).
Voyons maintenant un exemple:
Runnig abobve code dans la sortie du navigateur:
Selon la sortie que vous êtes à l'intérieur du contexte de l'objet fenêtre, il est également visible que le prototype de fenêtre se réfère à l'objet.
Essayons maintenant à l'intérieur d'une fonction:
Production:
La sortie est la même parce que nous avons enregistré «cette» variable dans la portée globale et nous l'avons enregistrée dans la portée fonctionnelle, nous n'avons pas changé le contexte. Dans les deux cas, le contexte était le même, lié à l' objet veuve .
Créons maintenant notre propre objet. En javascript, vous pouvez créer un objet de plusieurs façons.
Production:
Ainsi, à partir de l'exemple ci-dessus, nous avons constaté que «ce» mot-clé fait référence à un nouveau contexte lié à myObj, et myObject a également une chaîne de prototype vers Object.
Allons jeter un autre exemple:
sortie: est-ce logique? (lire les commentaires)
Si vous avez du mal à comprendre l'exemple ci-dessus, essayons avec notre propre rappel;
production:
Maintenant, comprenons la portée, le soi, l'IIFE et CECI comment se comporte
La sortie est assez impressionnante non?
la source
Réponse simple:
"ce" mot-clé dépend toujours du contexte d'invocation. Ils sont mentionnés ci-dessous.
LA FONCTION EST APPELÉE AVEC UN NOUVEAU MOT-CLÉ
Si la fonction est appelée avec un mot clé NEW, THIS sera liée à l'objet nouvellement créé.
Dans ce qui précède, cela sera lié à l'objet 'myCar'
LA FONCTION EST APPELÉE EXPLICITEMENT À L'AIDE D'APPELS ET DE MÉTHODES D'APPLICATION.
Dans ce cas, CECI sera lié à l'objet qui est explicitement transmis à la fonction.
SI LA FONCTION EST APPELÉE IMPLICITEMENT, CELA SERA LIÉ À CET OBJET
QUAND LA FONCTION EST APPELÉE SANS AUCUN CONTEXTE, CELA SERA LIÉ À UN OBJET MONDIAL
EN MODE STRICT, CELA SERA INDÉFINI
la source