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?
window
browser
undefined