To słowo kluczowe

Słowo kluczowe this odnosi się do wartości obiektu powiązanego z tagiem w momencie wywołania, co oznacza, że jego wartość różni się w zależności czy funkcja jest wywoływana jako metoda, samodzielna funkcja czy jako konstruktora.

Po wywołaniu funkcja tworzy wystąpienie słowa kluczowego this za jako odniesienia do obiektu pełniącego tę funkcję, dostęp do właściwości i metod zdefiniowanych w jej zakresie z zakresu. Praca z parametrem this jest pod wieloma względami podobny do pracy ze zmienną zadeklarowaną dzięki const. Podobnie jak stała, nie można usunąć funkcji this ani jej wartości ale metody i właściwości obiektu, które słowo kluczowe this można zmienić.

Globalne powiązanie

Poza funkcją lub kontekstem obiektu this odnosi się do globalThis, która w większości przypadków jest odniesieniem do obiektu globalnego Środowiska 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 globalThis jest obiektem global:

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

Poza trybem ścisłym właściwość this odnosi się też do obiektu globalnego w osobnym ponieważ obiekt nadrzędny Window jest obiektem, który rzeczywiście jest „właścicielem” tych funkcji.

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

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

W trybie ścisłym funkcja this ma wartość undefined w osobnym funkcja:

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

Przed wprowadzeniem trybu ścisłego wartość null lub undefined dla this zostałaby zastąpiona odwołaniem do obiektu globalnego. Czasami w komunikacie wiązanie globalne nazywane „wiązaniem domyślnym” z powodu tego starszego sposobu działania.

Powiązanie pośrednie

Gdy funkcja jest wywoływana jako metoda obiektu, wystąpienie this wewnątrz obiektu ta metoda odnosi się do obiektu zawierającego metodę, dając dostęp do metody metod i właściwości, które są z nim związane:

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

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

Może to wyglądać, że wartość this zależy od tego, jak funkcja i jej wartość obiekt nadrzędny jest zdefiniowany. Zamiast tego kontekst wartości this to obecny kontekst wykonania. W tym przypadku kontekstem wykonania jest fakt, Obiekt myObject wywołuje metodę myMethod, więc wartością jest myObject za this. Może się to wydawać kwestią techniczną w kontekście ale w przypadku bardziej zaawansowanych zastosowań this jest to niezbędne rozróżnienie, o kilku ważnych rzeczach.

Ogólnie używaj znaczników this w sposób, który nie powinien dotyczyć otaczającego kodu do dowolnej konstrukcji. Wyjątkiem od tej reguły jest ES5 Funkcje strzałek.

this w funkcjach strzałek

W funkcjach strzałek this łączy się w środowisko leksykalne. Oznacza to, że this w funkcji strzałki odnosi się do wartości this w tej funkcji najbliższy kontekst zamykający:

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() rejestruje obiekt myObject jako obiekt który jest „właścicielem” tę metodę, ale myObject.myArrowFunction() zwraca globalThis (lub undefined), ponieważ wystąpienie this w funkcji strzałki odnosi się do najwyższego zakresu nadrzędnego.

W poniższym przykładzie funkcja myEnclosingMethod tworzy funkcję strzałki na który zawiera go podczas wykonywania. Wystąpienie this w elemencie funkcja strzałki odnosi się teraz do wartości this w elemencie zamykającym czyli metody zawierającej tę funkcję strzałki. Ponieważ wartość this w myEnclosingMethod dotyczy myObject, po zdefiniuj funkcję strzałki, a 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() }

Jednoznaczne powiązanie

Powiązanie niejawne obsługuje większość przypadków użycia związanych z pracą z this. Musisz jednak może czasami potrzebować wartości this, aby uwzględnić konkretne wykonanie w kontekście systemu, a nie zakładanego kontekstu. Ilustracja, nawet nieco przestarzała, działa z 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

Chociaż ten konkretny mankament związany z setTimeout został już rozwiązany przez inne funkcje, podobne problemy z „utratą danych” Problemy dotyczące odbiorców this zostały już wcześniej rozwiązane tworząc wyraźne odwołanie do wartości this w zakresie zamierzonego kontekstu. Czasami możesz zauważyć przypisanie zadania this do zmiennej korzystającej z identyfikatorów takich jak that, self lub _this w starszej wersji w postaci baz kodu. Oto typowe konwencje identyfikatorów zmiennych zawierających przekazano wartość this.

Gdy wywołujesz funkcję za pomocą metody call(), bind() lub apply(), this wyraźnie 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."

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

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ływana w sposób, który ustawiałby wartość this na undefined lub null, ta wartość została zastąpiona przez globalThis poza zakresem ścisłym tryb:

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

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

Podobnie, jeśli funkcja zostanie wywołana w sposób, który dałby this obiekt podstawowy jest ona zastępowana obiekt 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, null lub undefined:

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

let myNumber = 10;

myFunction.call( myNumber );
> 10

myFunction.call( null );
> null

new powiązanie

Jeśli jako konstruktor używany jest class, 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 przy użyciu 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 który je wywołuje. W ramach 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 we wcześniejszym fragmencie kodu, efektem będzie obiekt elementu zawierający sam <button>:

> Button {}

Gdy funkcja strzałki jest używana jako wywołanie zwrotne detektora zdarzeń, wartość Pole this jest ponownie dostarczane przez najbliższy otaczający kontekst wykonania. Na górze na poziomie, co oznacza, że 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

Tak jak w przypadku każdego innego obiektu, gdy użyjesz funkcji call(), bind() lub apply() metody odwoływania się do funkcji wywołania zwrotnego detektora zdarzeń, this bezpośrednio 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 w przypadku skryptu działającego w przeglądarce? do których this odnosi się poza funkcją lub w kontekście obiektu?

Obiekt window
Obiekt browser
Obiekt undefined