Le mot clé this
fait référence à la valeur de l'objet lié à la fonction au moment de son appel, ce qui signifie que sa valeur est différente selon qu'une fonction est appelée en tant que méthode, en tant que fonction autonome ou en tant que constructeur.
Lorsqu'une fonction est appelée, elle crée en coulisses une instance du mot clé this
en tant que référence à l'objet qui contient cette fonction, ce qui permet d'accéder aux propriétés et aux méthodes définies à côté d'elle dans son champ d'application.
L'utilisation de this
est semblable, à certains égards, à celle d'une variable déclarée avec const
. Comme une constante, this
ne peut pas être supprimé et sa valeur ne peut pas être réaffectée, mais les méthodes et les propriétés de l'objet que contient le mot clé this
peuvent être modifiées.
Liaison globale
En dehors d'une fonction ou du contexte d'un objet, this
fait référence à la propriété globalThis
, qui est une référence à l'objet global dans la plupart des environnements JavaScript. Dans le contexte d'un script exécuté dans un navigateur Web, l'objet global est l'objet window
:
this;
> Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, ...}
Dans Node.js, globalThis
est l'objet global
:
$ node
Welcome to Node.js v20.10.0.
Type ".help" for more information.
> this
<ref *1> Object [global] {
...
}
En dehors du mode strict, this
fait également référence à l'objet global dans une fonction autonome, car le Window
parent est l'objet qui "possède" effectivement ces fonctions.
function myFunction() {
console.log( this );
}
myFunction();
> Window {...}
(function() {
console.log( this );
}());
> Window {...}
Lorsque vous utilisez le mode strict, this
a une valeur de undefined
dans une fonction autonome:
(function() {
"use strict";
console.log( this );
}());
> undefined
Avant l'introduction du mode strict, une valeur null
ou undefined
pour this
était remplacée par une référence à l'objet global. En raison de ce comportement ancien, vous pouvez parfois voir la liaison globale appelée "liaison par défaut".
Liaison implicite
Lorsqu'une fonction est appelée en tant que méthode d'un objet, une instance de this
dans cette méthode fait référence à l'objet qui contient la méthode, ce qui permet d'accéder aux méthodes et aux propriétés qui se trouvent à côté:
let myObject = {
myValue: "This is my string.",
myMethod() {
console.log( this.myValue );
}
};
myObject.myMethod();
> "This is my string."
Il peut sembler que la valeur de this
dépend de la manière dont une fonction et son objet englobant sont définis. À la place, le contexte de la valeur de this
est le contexte d'exécution actuel. Dans ce cas, le contexte d'exécution est tel que l'objet myObject
appelle la méthode myMethod
. myObject
est donc la valeur de this
. Cela peut sembler être une question technique dans le contexte des exemples précédents, mais pour les utilisations plus avancées de this
, il s'agit d'une distinction essentielle à garder à l'esprit.
En règle générale, utilisez this
de manière à ne pas vous attendre à ce que le code environnant ait une structure particulière. L'exception à cette règle concerne les fonctions flèches ES5.
this
dans les fonctions de flèche
Dans les fonctions flèche, this
se résout en un lien dans un environnement englobant lexicalement. Cela signifie que this
dans une fonction à flèche fait référence à la valeur de this
dans le contexte le plus proche de cette fonction:
let myObject = {
myMethod() { console.log( this ); },
myArrowFunction: () => console.log( this ),
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myMethod();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
myObject.myArrowFunction();
> Window {...}
Dans l'exemple précédent, myObject.myMethod()
consigne myObject
en tant qu'objet "propriétaire" de cette méthode, mais myObject.myArrowFunction()
renvoie globalThis
(ou undefined
), car l'instance de this
dans la fonction flèche fait plutôt référence au champ d'application le plus englobant.
Dans l'exemple suivant, myEnclosingMethod
crée une fonction flèche sur l'objet qui la contient lorsqu'elle est exécutée. L'instance de this
dans la fonction fléchée fait désormais référence à la valeur de this
dans l'environnement englobant, qui est la méthode contenant cette fonction fléchée. Étant donné que la valeur de this
dans myEnclosingMethod
fait référence à myObject
, une fois que vous avez défini la fonction à flèche, this
dans la fonction à flèche fait également référence à myObject
:
let myObject = {
myMethod() { console.log( this ); },
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myEnclosingMethod();
myObject.myArrowFunction();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
Liaison explicite
Le forçage implicite gère la plupart des cas d'utilisation de this
. Toutefois, vous devrez peut-être parfois utiliser la valeur de this
pour représenter un contexte d'exécution spécifique au lieu du contexte supposé. Un exemple illustratif, bien que légèrement obsolète, consiste à travailler avec this
dans la fonction de rappel d'un setTimeout
, car ce rappel a un contexte d'exécution unique:
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
myObject.myMethod();
> "This is my string."
setTimeout( myObject.myMethod, 100 );
> undefined
Bien que ce défaut spécifique de setTimeout
ait été résolu par la suite par d'autres fonctionnalités, des problèmes similaires de "perte" de this
ont déjà été résolus en créant une référence explicite à la valeur de this
dans le champ d'application du contexte prévu. Vous pouvez parfois voir des instances de this
attribuées à une variable à l'aide d'identifiants tels que that
, self
ou _this
dans les anciens codebases. Il s'agit de conventions d'identifiant courantes pour les variables contenant une valeur this
transmise.
Lorsque vous appelez une fonction à l'aide des méthodes call()
, bind()
ou apply()
, this
fait référence explicitement à l'objet appelé:
let myFunction = function() {
console.log( this.myValue );
}
let myObject = {
"myValue" : "This is my string."
};
myFunction.call( myObject );
> "This is my string."
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
setTimeout( myObject.myMethod.bind( myObject ), 100 );
> "This is my string."
La liaison explicite remplace la valeur this
fournie par la liaison implicite.
let myObject = {
"myValue" : "This string sits alongside myMethod.",
myMethod() {
console.log( this.myValue );
}
};
let myOtherObject = {
"myValue" : "This is a string in another object entirely.",
};
myObject.myMethod.call( myOtherObject );
> "This is a string in another object entirely."
Si une fonction est appelée de manière à définir la valeur de this
sur undefined
ou null
, cette valeur est remplacée par globalThis
en dehors du mode strict:
let myFunction = function() {
console.log( this );
}
myFunction.call( null );
> Window {...}
De même, si une fonction est appelée de manière à donner à this
une valeur primitive, cette valeur est remplacée par l'objet wrapper de la valeur primitive en dehors du mode strict:
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> Number { 10 }
En mode strict, une valeur this
transmise n'est en aucun cas forcée à un objet, même s'il s'agit d'une valeur primitive, null
ou undefined
:
"use strict";
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> 10
myFunction.call( null );
> null
Liaison new
Lorsqu'une classe est utilisée comme constructeur à l'aide du mot clé new
, this
fait référence à l'instance nouvellement créée:
class MyClass {
myString;
constructor() {
this.myString = "My string.";
}
logThis() {
console.log( this );
}
}
const thisClass = new MyClass();
thisClass.logThis();
> Object { myString: "My string." }
De même, la valeur de this
dans une fonction de constructeur appelée à l'aide de new
fait référence à l'objet en cours de création:
function MyFunction() {
this.myString = "My string.";
this.logThis = function() {
console.log( this );
}
}
const myObject = new MyFunction();
myObject.logThis();
> Object { myString: "My string.", logThis: logThis() }
Liaison de gestionnaire d'événements
Dans le contexte des gestionnaires d'événements, la valeur de this
fait référence à l'objet qui l'appelle. Dans la fonction de rappel d'un gestionnaire d'événements, cela signifie que this
fait référence à l'élément associé au gestionnaire:
let button = document.querySelector( "button" );
button.addEventListener( "click", function( event ) { console.log( this ); } );
Lorsqu'un utilisateur interagit avec le button
dans l'extrait précédent, le résultat est l'objet élément contenant le <button>
lui-même:
> Button {}
Lorsqu'une fonction fléchée est utilisée comme rappel d'écouteur d'événements, la valeur de this
est à nouveau fournie par le contexte d'exécution le plus proche. Au niveau supérieur, cela signifie que this
dans une fonction de rappel de gestionnaire d'événements est globalThis
:
let button = document.querySelector( "button" );
button.addEventListener( "click", ( event ) => { console.log( this ); } );
> undefined
Comme pour tout autre objet, lorsque vous utilisez les méthodes call()
, bind()
ou apply()
pour faire référence à la fonction de rappel d'un écouteur d'événements, this
fait référence à l'objet explicitement:
let button = document.querySelector( "button" );
let myObject = {
"myValue" : true
};
function handleClick() {
console.log( this );
}
button.addEventListener( "click", handleClick.bind( myObject ) );
> Object { myValue: true }
Vérifier vos connaissances
Pour un script exécuté dans un navigateur Web, à quoi fait référence this
lorsqu'il est utilisé en dehors d'une fonction ou du contexte d'un objet ?
window
browser
undefined