To słowo kluczowe

Słowo kluczowe this odnosi się do wartości obiektu, który jest powiązany z funkcją w momencie jej wywołania. Oznacza to, że jej wartość różni się w zależności od tego, czy funkcja zostanie wywołana jako metoda, jako funkcja samodzielna czy konstruktor.

Wywołanie funkcji tworzy w tle wystąpienie słowa kluczowego this jako odwołanie do obiektu zawierającego tę funkcję, zapewniając dostęp z poziomu jej zakresu do właściwości i metod zdefiniowanych obok niej. Praca z tabelą this przypomina pracę ze zmienną zadeklarowaną w polu const. Tak jak w przypadku stałej funkcji this, nie można usunąć ani zmienić jej wartości, ale można zmieniać metody i właściwości obiektu, które zawiera słowo kluczowe this.

Powiązanie globalne

Poza funkcją lub kontekstem obiektu this odnosi się do właściwości globalThis, która jest odniesieniem do obiektu globalnego w większości środowisk JavaScript. W kontekście skryptu uruchomionego w przeglądarce obiekt globalny jest obiektem window:

this;
> Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, ...}

W Node.js obiekt globalThis to global:

$ node
Welcome to Node.js v20.10.0.
Type ".help" for more information.
> this
<ref *1> Object [global] {
...
}

Poza trybem ścisłym this odnosi się też do obiektu globalnego wewnątrz funkcji samodzielnej, ponieważ obiekt nadrzędny Window jest obiektem, który w praktyce „jest właścicielem” tych funkcji.

function myFunction() {
    console.log( this );
}
myFunction();
> Window {...}

(function() {
    console.log( this );
}());
> Window {...}

W trybie ścisłym this ma wartość undefined w samodzielnej funkcji:

(function() {
    "use strict";
    console.log( this );
}());
> undefined

Przed wprowadzeniem trybu ścisłego wartość null lub undefined dla this była zastępowana odwołaniem do obiektu globalnego. Ze względu na to starsze zachowanie czasami wiązanie globalne może być określane jako „powiązanie domyślne”.

Powiązanie niejawne

Gdy funkcja jest wywoływana jako metoda obiektu, wystąpienie this w tej metodzie odnosi się do obiektu zawierającego tę metodę, co daje dostęp do metod i właściwości znajdujących się obok niej:

let myObject = {
    myValue: "This is my string.",
    myMethod() {
            console.log( this.myValue );
    }
};

myObject.myMethod();
> "This is my string."

Może wyglądać tak, jak wartość this zależy od tego, jak zdefiniowano funkcję i jej obiekt otaczający. Zamiast tego kontekst dla wartości this to bieżący kontekst wykonania. W tym przypadku kontekst wykonania jest taki, że obiekt myObject wywołuje metodę myMethod, więc myObject jest wartością funkcji this. W kontekście poprzednich przykładów może się to wydawać kwestią techniczną, ale w przypadku bardziej zaawansowanych zastosowań this jest to istotne rozróżnienie, o którym trzeba pamiętać.

Ogólnie używaj polecenia this w sposób, który nie oczekuje, że otaczający kod będzie miał określoną strukturę. Wyjątkiem od tej reguły są funkcje strzałek w standardzie ES5.

this w funkcjach strzałek

W funkcjach strzałek parametr this przyjmuje wartość wiążącą w środowisku zamkniętym (leksyktycznie). Oznacza to, że this w funkcji strzałki odnosi się do wartości this w najbliższym kontekście tej funkcji:

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 {...}

W poprzednim przykładzie myObject.myMethod() loguje myObject jako obiekt, który jest „właścicielem” tej metody, ale myObject.myArrowFunction() zwraca globalThis (lub undefined), ponieważ wystąpienie this w funkcji strzałki odnosi się zamiast do najwyższego zakresu obejmującego.

W poniższym przykładzie myEnclosingMethod tworzy w obiekcie funkcję strzałki, która zawiera ją podczas wykonywania. Wystąpienie this w funkcji strzałki odnosi się teraz do wartości this w środowisku nadrzędnym, czyli metodzie zawierającej tę funkcję strzałki. Ponieważ wartość this w elemencie myEnclosingMethod odnosi się do myObject, po zdefiniowaniu funkcji strzałki, this w funkcji strzałki odnosi się również do myObject:

let myObject = {
    myMethod() { console.log( this ); },
    myEnclosingMethod: function () {
        this.myArrowFunction = () => { console.log(this) };
    }
};

myObject.myEnclosingMethod();
myObject.myArrowFunction();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }

Jawne powiązanie

Powiązanie niejawne obsługuje większość przypadków użycia podczas pracy z właściwością this. Czasami jednak wartość this może być potrzebna, aby reprezentować konkretny kontekst wykonania zamiast zakładanego kontekstu. Przykładowy przykład, który może być nieco nieaktualny, pokazuje działanie funkcji this w ramach funkcji wywołania zwrotnego setTimeout, ponieważ to wywołanie zwrotne ma unikalny kontekst wykonania:

var myObject = {
  myString: "This is my string.",
  myMethod() {
    console.log( this.myString );
  }
};
myObject.myMethod();
> "This is my string."

setTimeout( myObject.myMethod, 100 );
> undefined

Mimo że to konkretne niedobór funkcji setTimeout zostało już rozwiązanych przez inne funkcje, podobne problemy związane z „utratą” this eliminowano wcześniej, podając wyraźne odniesienie do wartości this w ramach zamierzonego kontekstu. Czasami w starszych bazach kodu możesz zauważyć, że zmienna this jest przypisywana do zmiennej za pomocą identyfikatorów takich jak that, self lub _this. Oto typowe konwencje identyfikatorów w przypadku zmiennych zawierających przekazaną wartość this.

Gdy wywołujesz funkcję za pomocą metody call(), bind() lub apply(), this jawnie odwołuje się do wywoływanego obiektu:

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."

Jawne wiązanie zastępuje wartość this podaną przez niejawne wiązanie.

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."

Jeśli funkcja jest wywołana w sposób, który spowodowałby ustawienie wartości this na undefined lub null, ta wartość jest zastępowana przez globalThis poza trybem ścisłym:

let myFunction = function() {
    console.log( this );
}

myFunction.call( null );
> Window {...}

Podobnie, jeśli funkcja jest wywoływana w sposób, który daje this wartość prostą, wartość ta jest zastępowana obiektem otoki wartości podstawowej poza trybem ścisłym:

let myFunction = function() {
    console.log( this );
}

let myNumber = 10;

myFunction.call( myNumber );
> Number { 10 }

W trybie ścisłym przekazywana wartość this nie jest w żaden sposób przekształcana w obiekt, nawet jeśli jest to wartość podstawowa albo null lub undefined:

"use strict";
let myFunction = function() {
    console.log( this );
}

let myNumber = 10;

myFunction.call( myNumber );
> 10

myFunction.call( null );
> null

Powiązanie new

Jeśli klasa jest używana jako konstruktor wykorzystujący słowo kluczowe new, this odnosi się do nowo utworzonej instancji:

class MyClass {
    myString;
    constructor() {
        this.myString = "My string.";
    }
    logThis() {
        console.log( this );
    }
}
const thisClass = new MyClass();

thisClass.logThis();
> Object { myString: "My string." }

Podobnie wartość this w funkcji konstruktora wywoływanej za pomocą new odnosi się do tworzonego obiektu:

function MyFunction() {
  this.myString = "My string.";
  this.logThis = function() {
    console.log( this );
  }
}
const myObject = new MyFunction();

myObject.logThis();
> Object { myString: "My string.", logThis: logThis() }

Powiązanie modułu obsługi zdarzeń

W kontekście modułów obsługi zdarzeń wartość this odwołuje się do obiektu, który je wywołuje. W funkcji wywołania zwrotnego modułu obsługi zdarzeń oznacza to, że this odwołuje się do elementu powiązanego z modułem obsługi:

let button = document.querySelector( "button" );

button.addEventListener( "click", function( event ) { console.log( this ); } );

Gdy użytkownik wejdzie w interakcję z elementem button w poprzednim fragmencie, wynikiem będzie obiekt elementu zawierający sam obiekt <button>:

> Button {}

Jeśli funkcja strzałki jest używana jako wywołanie zwrotne detektora zdarzeń, wartość this jest ponownie dostarczana przez najbliższy kontekst wykonania. Na najwyższym poziomie oznacza to, że funkcja this w funkcji wywołania zwrotnego modułu obsługi zdarzeń to globalThis (lub undefined w trybie ścisłym):

let button = document.querySelector( "button" );

button.addEventListener( "click", ( event ) => { console.log( this ); } );
> undefined

Podobnie jak w przypadku innych obiektów, gdy używasz metody call(), bind() lub apply(), aby odwołać się do funkcji wywołania zwrotnego odbiornika, this wyraźnie odwołuje się do obiektu:

let button = document.querySelector( "button" );
let myObject = {
    "myValue" : true
};
function handleClick() {
    console.log( this );
}

button.addEventListener( "click", handleClick.bind( myObject ) );
> Object { myValue: true }

Sprawdź swoją wiedzę

Jaki jest obiekt globalny this w przypadku skryptu uruchomionego w przeglądarce, gdy jest używany poza funkcją lub w kontekście obiektu?

Obiekt window
Obiekt browser
Obiekt undefined