Ce mot clé

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 ?

L'objet window
L'objet browser
L'objet undefined