zrozumienie tego, Bind, wywołanie i zastosowanie w JavaScript

zrozumienie tego, Bind, wywołanie i zastosowanie w JavaScript

Ten artykuł został pierwotnie napisany dla DigitalOcean.

słowo kluczowethis jest bardzo ważnym pojęciem w JavaScript, a także szczególnie mylącym zarówno dla nowych programistów, jak i tych, którzy mają doświadczenie w innych językach programowania. W JavaScript this jest odniesieniem do obiektu., Obiekt, do którego odnosi się this, może się różnić, pośrednio w zależności od tego, czy jest globalny, w obiekcie, czy w konstruktorze, a także może się różnić bezpośrednio w zależności od użycia metod prototypowych bind, call, oraz apply.

chociażthis jest nieco skomplikowanym tematem, jest to również taki, który pojawia się zaraz po rozpoczęciu pisania pierwszych programów JavaScript., Niezależnie od tego, czy próbujesz uzyskać dostęp do elementu lub zdarzenia w modelu obiektowym dokumentu (DOM), budujesz klasy do pisania w stylu programowania obiektowego, czy używasz właściwości i metod zwykłych obiektów, napotkasz this.

w tym artykule dowiesz się, co this odnosi się do niejawnie w oparciu o kontekst, a także dowiesz się, jak używać metod bind, call I apply do jawnego określ wartość this.,

kontekst Niejawny

istnieją cztery główne konteksty, w których wartośćthis może być domniemana:

  • kontekst globalny
  • jako metoda wewnątrz obiektu
  • jako konstruktor funkcji lub Klasy
  • jako Obsługa zdarzenia Dom

Globalny

w kontekście globalnym,this odnosi się do obiektu globalnego. Gdy pracujesz w przeglądarce, kontekst Globalny to window. Kiedy pracujesz w Node.js, globalny kontekst to global.,

Uwaga: Jeśli nie znasz jeszcze pojęcia zakresu w JavaScript, zapoznaj się ze zrozumieniem zmiennych, zakresu i podnoszenia w JavaScript.

w przykładach możesz przećwiczyć kod w konsoli narzędzi programistycznych przeglądarki. Przeczytaj, Jak korzystać z konsoli programistów JavaScript, jeśli nie jesteś zaznajomiony z uruchomieniem kodu JavaScript w przeglądarce.

Jeśli zarejestrujesz wartość this bez żadnego innego kodu, zobaczysz, do czego odnosi się obiekt this.,

console.log(this)
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}

thistowindow, który jest globalnym obiektem przeglądarki.

rozumiejąc zmienne, zakres i podnoszenie w JavaScript, nauczyłeś się, że funkcje mają swój własny kontekst dla zmiennych. Możesz pokusić się o stwierdzenie, że this stosowałby te same zasady wewnątrz funkcji, ale tak nie jest. Funkcja najwyższego poziomu nadal zachowuje odniesieniethis do obiektu globalnego.,

piszesz funkcję najwyższego poziomu lub funkcję, która nie jest powiązana z żadnym obiektem, jak to:

function printThis() { console.log(this)}printThis()
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}

nawet wewnątrz funkcji, this odnosi się do window lub obiektu globalnego.

jednak, gdy używasz trybu ścisłego, kontekstthis w ramach funkcji w kontekście globalnym będzieundefined.,

'use strict'function printThis() { console.log(this)}printThis()
undefined

ogólnie rzecz biorąc, bezpieczniej jest użyć trybu ścisłego, aby zmniejszyć prawdopodobieństwo wystąpienia nieoczekiwanego zakresuthis. Rzadko ktoś chce odwołać się do obiektu window używając this.

aby uzyskać więcej informacji na temat trybu ścisłego i jakie zmiany wprowadza w odniesieniu do błędów i bezpieczeństwa, przeczytaj dokumentację trybu ścisłego na MDN.,

metoda obiektowa

metoda jest funkcją obiektu lub zadaniem, które obiekt może wykonać. Metoda używa this w celu odniesienia się do Właściwości obiektu.

"The United States of America was founded in 1776."

w tym przykładziethis jest taki sam jakamerica.

w zagnieżdżonym obiekcie this odnosi się do bieżącego zakresu obiektu metody. W poniższym przykładzie this.symbol w obrębie details obiekt odnosi się do details.symbol.,

"The symbol is the eagle and the currency is USD."

innym sposobem myślenia o tym jest to, żethis odnosi się do obiektu po lewej stronie kropki podczas wywoływania metody.

Konstruktor funkcji

gdy używasz słowa kluczowego new, tworzy on instancję konstruktora funkcji lub klasy. Konstruktory funkcji były standardowym sposobem inicjalizacji obiektu zdefiniowanego przez użytkownika przed wprowadzeniem składni class w aktualizacji ECMAScript 2015 Do JavaScript., W Understanding Classes in JavaScript dowiesz się, jak stworzyć konstruktor funkcji i równoważny konstruktor klasy.

"The United States of America was founded in 1776."

w tym kontekściethis jest teraz powiązany z instancjąCountry, która jest zawarta w stałejamerica.

konstruktor klasy

konstruktor klasy działa tak samo jak konstruktor funkcji. Przeczytaj więcej o podobieństwach i różnicach między konstruktorami funkcji a klasami ES6 w zrozumieniu klas w JavaScript.,

this wdescribe metoda odnosi się do instancjiCountry, która jestamerica.

"The United States of America was founded in 1776."

Obsługa zdarzeń DOM

w przeglądarce znajduje się specjalny kontekstthis dla obsługi zdarzeń. W programie obsługi zdarzeń wywołanym przez addEventListener, this będzie odnosić się do event.currentTarget., Najczęściej programiści będą po prostu używać event.target lub event.currentTarget w razie potrzeby, aby uzyskać dostęp do elementów w DOM, ale ponieważthis zmiany odniesienia w tym kontekście, ważne jest, aby wiedzieć.

w poniższym przykładzie utworzymy przycisk, dodamy do niego tekst i dodamy go do DOM. Gdy zarejestrujemy wartość this wewnątrz procedury obsługi zdarzenia, wyświetli ona obiekt docelowy.,

<button>Click me</button>

gdy wkleisz to do swojej przeglądarki, zobaczysz przycisk dołączony do strony z napisem „Kliknij mnie”. Jeśli klikniesz przycisk, zobaczysz <button>Click me</button> w konsoli, ponieważ kliknięcie przycisku rejestruje element, który jest samym przyciskiem. Dlatego, jak widzisz, this odnosi się do elementu docelowego, do którego dodaliśmy detektor zdarzeń.,

jawny kontekst

we wszystkich poprzednich przykładach wartośćthis była określona przez jej kontekst—czy jest globalny, w obiekcie, w skonstruowanej funkcji lub klasie, czy w obsłudze zdarzenia DOM. Jednak, używając call, apply lub bind, możesz jednoznacznie określić, do czego odnosi się this.,

trudno jest dokładnie określić, kiedy należy używać call,applylubbind, ponieważ będzie to zależało od kontekstu programu. bind może być szczególnie pomocny, gdy chcesz użyć zdarzeń, aby uzyskać dostęp do właściwości jednej klasy w innej klasie. Na przykład, jeśli miałbyś napisać prostą grę, możesz oddzielić interfejs użytkownika i I / O w jedną klasę, A logikę i stan gry w inną., Ponieważ logika gry musiałaby mieć dostęp do danych wejściowych, takich jak naciśnięcie klawisza i kliknięcie, chcesz bind zdarzenia, aby uzyskać dostęp do this wartość klasy logiki gry.

ważną częścią jest wiedzieć, jak określić, do którego obiektu odnosi się this, co można zrobić pośrednio z tym, czego nauczyłeś się w poprzednich sekcjach, lub bezpośrednio z trzema metodami, których nauczysz się następnie.,

wywołanie i zastosowanie

call Iapply są bardzo podobne—wywołują funkcję z podanym kontekstemthis I opcjonalnymi argumentami. Jedyną różnicą pomiędzy callI applyjest to, że callwymaga przekazywania argumentów jeden po drugim, a apply pobiera argumenty jako tablicę.,

w tym przykładzie utworzymy obiekt i utworzymy funkcję, która odwołuje się dothis ale nie mathis kontekstu.

"undefined was written by undefined"

ponieważ summary I book nie mają połączenia, wywołanie summary samo w sobie wydrukuje tylko undefined, ponieważ szuka tych właściwości na obiekcie globalnym.,

Uwaga: próba tego w trybie ścisłym spowodowałabyUncaught TypeError: Cannot read property 'title' of undefined, ponieważthis sama byłabyundefined.

jednak możesz użyć call I apply aby wywołać this kontekst book w funkcji.,

summary.call(book)// or:summary.apply(book)
"Brave New World was written by Aldous Huxley."

istnieje teraz połączenie pomiędzybook Isummary gdy te metody są stosowane. Potwierdźmy dokładnie, czym jest this.

function printThis() { console.log(this)}printThis.call(book)// or:whatIsThis.apply(book)
{title: "Brave New World", author: "Aldous Huxley"}

w tym przypadkuthis staje się obiektem przekazanym jako argument.

w ten sposóbcall Iapply są takie same, ale jest jedna mała różnica., Oprócz możliwości przekazania kontekstu this jako pierwszego argumentu, możesz również przekazać dodatkowe argumenty.

function longerSummary(genre, year) { console.log( `${this.title} was written by ${this.author}. It is a ${genre} novel written in ${year}.`, )}

zcall każda dodatkowa wartość, którą chcesz przekazać, jest wysyłana jako dodatkowy argument.,

longerSummary.call(book, 'dystopian', 1932)
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."

Jeśli spróbujesz wysłać dokładnie te same argumenty za pomocą apply, dzieje się tak:

longerSummary.apply(book, 'dystopian', 1932)
Uncaught TypeError: CreateListFromArrayLike called on non-object at <anonymous>:1:15

zamiast tego, dla apply, musisz przekazać wszystkie argumenty w tablicy.

longerSummary.apply(book, )
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."

różnica między przekazywaniem argumentów pojedynczo lub w tablicy jest subtelna, ale należy o tym pamiętać., Może być prostsze i wygodniejsze w użyciu apply, ponieważ nie wymagałoby to zmiany wywołania funkcji, gdyby niektóre szczegóły parametrów uległy zmianie.

Bind

zarówno call, jak i applysą metodami jednorazowego użytku-jeśli wywołasz metodę z kontekstem this, będzie ona miała tę funkcję, ale oryginalna funkcja pozostanie niezmieniona.,

czasami może być konieczne używanie metody w kółko z kontekstemthis innego obiektu, a w takim przypadku można użyć metodybind, aby utworzyć zupełnie nową funkcję z jawnie powiązanąthis.

const braveNewWorldSummary = summary.bind(book)braveNewWorldSummary()
"Brave New World was written by Aldous Huxley"

w tym przykładzie za każdym razem, gdy wywołasz braveNewWorldSummary, zawsze zwróci oryginalny this wartość związana z nim., Próba przypisania do niej nowego kontekstu thisnie powiedzie się, więc zawsze możesz zaufać powiązanej funkcji, która zwróci oczekiwaną wartość this.

chociaż ten przykład próbuje powiązaćbraveNewWorldSummary po raz kolejny, zachowuje oryginalny kontekstthis od momentu pierwszego związania.

funkcje strzałek

funkcje strzałek nie mają własnych this Wiązanie. Zamiast tego, idą do następnego poziomu egzekucji.,

przydatne może być użycie funkcji strzałki w przypadkach, gdy naprawdę chceszthis, aby odnieść się do zewnętrznego kontekstu. Na przykład, jeśli wewnątrz klasy znajduje się detektor zdarzeń, prawdopodobnie chcesz, aby this odnosił się do pewnej wartości w klasie.

w tym przykładzie utworzysz i dodasz przycisk do DOM tak jak poprzednio, ale klasa będzie miała detektor zdarzeń, który zmieni wartość tekstową przycisku po kliknięciu.

Jeśli klikniesz przycisk, zawartość tekstowa zmieni się na wartośćbuttonText., Jeśli nie użyłbyś tutaj funkcji strzałki, this byłby równy event.currentTarget I nie byłbyś w stanie użyć jej do uzyskania dostępu do wartości w klasie bez jej jawnego powiązania. Ta taktyka jest często używana na metodach klasowych w frameworkach takich jak React.

podsumowanie

w tym artykule dowiedzieliśmy się o this w JavaScript i wielu różnych wartościach, które może mieć na podstawie niejawnego wiązania runtime i jawnego wiązania za pomocą bind, call I apply., Dowiedzieliście się również, jak brak powiązania this w funkcjach strzałek może być używany do odwoływania się do innego kontekstu. Dzięki tej wiedzy powinieneś być w stanie określić wartość this w swoich programach.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *