Tento článek byl původně napsán pro DigitalOcean.
this
klíčové slovo je velmi důležité pojetí v Javascriptu, a také obzvlášť matoucí pro nové vývojáře a ty, kteří mají zkušenosti v jiných programovacích jazycích. V JavaScriptu jethis
odkaz na objekt., Objekt, který this
vztahuje se může lišit, implicitně založena na tom, zda je globální, na objektu, nebo v konstruktoru, a může se také lišit výslovně na základě používání Function
prototyp metody bind
call
, a apply
.
ačkoli this
je trochu složité téma, je to také téma, které se objeví, jakmile začnete psát své první programy JavaScript., Ať už jste se snaží přístup k prvku nebo událostí v DOM (Document Object Model), budovy třídy pro psaní v objektově-orientovaný programovací styl, nebo pomocí vlastnosti a metody pravidelné objekty, se setkáte this
.
V tomto článku se dozvíte, co this
odkazuje implicitně na základě kontextu, a vy se dozvíte, jak používat bind
call
, a apply
metody explicitně určit hodnotu this
.,
Implicitní Kontext
k Dispozici jsou čtyři hlavní kontexty, v níž hodnota this
lze implicitně odvodit:
- globální souvislosti
- jako metoda v rámci objektu
- jako konstruktér na funkce nebo třídy
- jako DOM event handler
Globální
V globálním kontextu, this
odkazuje na globální objekt. Když pracujete v prohlížeči, globální kontext je window
. Když pracujete v uzlu.js, globální kontext je global
.,
Poznámka: Pokud ještě nejste obeznámeni s konceptem rozsahu v JavaScriptu, přečtěte si porozumění proměnným, rozsahu a zvedání v JavaScriptu.
pro příklady budete cvičit kód v konzoli nástrojů pro vývojáře prohlížeče. Přečtěte si, jak používat konzolu pro vývojáře JavaScriptu, pokud nejste obeznámeni se spuštěním kódu JavaScript v prohlížeči.
Pokud se přihlásíte hodnota this
bez jakékoliv další kód, uvidíte, co objekt this
odkazuje.,
console.log(this)
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
můžete vidět, že this
window
, což je globální objekt prohlížeče.
v porozumění proměnným, rozsahu a zvedání v JavaScriptu jste se dozvěděli, že funkce mají svůj vlastní kontext pro proměnné. Možná budete v pokušení myslet si, že this
bude dodržovat stejná pravidla uvnitř funkce, ale ne. Funkce nejvyšší úrovně si stále ponechá odkazthis
globálního objektu.,
napsat top-level funkce, nebo funkce, která není spojena s žádným objektem, jako je tento:
function printThis() { console.log(this)}printThis()
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
Dokonce i v rámci funkce, this
stále odkazuje na window
, nebo globální objekt.
při použití přísného režimu však bude kontext this
v rámci funkce v globálním kontextu undefined
.,
'use strict'function printThis() { console.log(this)}printThis()
undefined
Obecně platí, že je bezpečnější k použití přísného režimu, aby se snížila pravděpodobnost this
s nečekaným rozsahem. Zřídka bude někdo chtít odkazovat na objekt window
pomocí this
.
pro více informací o přísném režimu a změnách, které dělá, pokud jde o chyby a bezpečnost, přečtěte si dokumentaci přísného režimu na MDN.,
metoda objektu
metoda je funkce na objektu nebo úkol, který může objekt provést. Metoda používá this
odkazovat na Vlastnosti objektu.
"The United States of America was founded in 1776."
V tomto příkladu this
je stejné jako america
.
v vnořeném objektu, this
odkazuje na aktuální rozsah objektu metody. V následujícím příkladu, this.symbol
v details
objekt odkazuje na details.symbol
.,
"The symbol is the eagle and the currency is USD."
Další způsob, jak přemýšlet o tom je, že this
odkazuje na objekt na levé straně, tečku, když se volání metody.
a function Constructor
Když použijetenew
Klíčové slovo, vytvoří instanci funkce konstruktoru nebo třídy. Konstruktory funkcí byly standardním způsobem inicializace uživatelem definovaného objektu před zavedením syntaxeclass
v aktualizaci ECMAScript 2015 do JavaScriptu., Při porozumění třídám v JavaScriptu se naučíte, jak vytvořit Konstruktor funkcí a ekvivalentní Konstruktor třídy.
"The United States of America was founded in 1776."
V tomto kontextu, this
je nyní vázána k instanci Country
, který je obsažen v america
konstantní.
a class Constructor
Konstruktor na třídě působí stejně jako konstruktor na funkci. Přečtěte si více o podobnostech a rozdílech mezi konstruktory funkcí a třídami ES6 v porozumění třídám v JavaScriptu.,
this
describe
metoda se vztahuje k instanci Country
, což je america
.
"The United States of America was founded in 1776."
DOM Event Handler
V prohlížeči, je speciální this
kontext pro obslužné rutiny událostí. V případě handler volal addEventListener
, this
bude odkazovat na event.currentTarget
., Více často než ne, budou vývojáři jednoduše použít event.target
nebo event.currentTarget
podle potřeby, aby přístup k prvkům v DOM, ale protože this
referenční změny v této souvislosti je důležité vědět.
v následujícím příkladu vytvoříme tlačítko, přidáme do něj text a připojíme jej k DOM. Když zaznamenáme hodnotu this
v rámci obslužného programu událostí, vytiskne cíl.,
jakmile to vložíte do prohlížeče, zobrazí se tlačítko připojené ke stránce s nápisem „klikněte na mě“. Pokud kliknete na tlačítko, zobrazí se v konzole <button>Click me</button>
, protože kliknutím na tlačítko se přihlásí prvek, což je samotné tlačítko. Proto, jak vidíte, this
odkazuje na cílené prvek, což je prvek, který jsme přidán posluchač události.,
Explicitní Kontext
Ve všech předchozích příkladech, hodnota this
byla určena jeho kontextu—zda je globální, a to v objektu, v početně funkce nebo třídy, nebo na DOM event handler. Nicméně, s použitím call
apply
nebo bind
, můžete výslovně určit, co this
by se měla týkat.,
je obtížné přesně definovat, kdy použít call
apply
nebo bind
, protože to bude záviset na kontextu vašeho programu. bind
může být zvláště užitečné, pokud chcete použít události pro přístup k vlastnostem jedné třídy v jiné třídě. Například, pokud byste měli napsat jednoduchou hru, můžete oddělit uživatelské rozhraní a I / O do jedné třídy a herní logiku a stát do druhé., Protože hra logiky by třeba, aby přístup vstup, jako je stisknutí tlačítka a klepněte na tlačítko, budete chtít, aby bind
události vstup do this
hodnota hry logika třídy.
důležité je vědět, jak určit, co objekt this
označuje, které můžete udělat implicitně s tím, co jste se naučili v předchozí části, nebo explicitně s tři metody, budete vedle.,
Volání a Použít
call
apply
jsou velmi podobné—vyvolání funkce se stanovenou this
kontextu, a volitelné argumenty. Jediný rozdíl mezi call
apply
call
vyžaduje argumenty, které mají být předány v jednom, a apply
trvá argumenty jako pole.,
v tomto příkladu vytvoříme objekt a vytvoříme funkci, která odkazuje na this
ale nemáthis
kontext.
"undefined was written by undefined"
, Protože summary
book
mít žádná spojení, s odvoláním summary
sám o sobě bude tisknout pouze undefined
, tak to hledá ty vlastnosti, které na globální objekt.,
Poznámka: Pokusem to v přísném režimu by měla za následek
Uncaught TypeError: Cannot read property 'title' of undefined
this
by samo o sobě býtundefined
.
Nicméně, můžete použít call
apply
vyvolat this
kontextu book
na funkci.,
summary.call(book)// or:summary.apply(book)
"Brave New World was written by Aldous Huxley."
Existuje spojení mezi book
summary
když jsou tyto metody použity. Potvrzme přesně, co je this
.
function printThis() { console.log(this)}printThis.call(book)// or:whatIsThis.apply(book)
{title: "Brave New World", author: "Aldous Huxley"}
V tomto případě this
vlastně stává objekt předán jako argument.
takto jsou call
a apply
stejné, ale existuje jeden malý rozdíl., Kromě toho, že můžete jako první argument předat kontext this
, můžete také předat další argumenty.
function longerSummary(genre, year) { console.log( `${this.title} was written by ${this.author}. It is a ${genre} novel written in ${year}.`, )}
call
každé další hodnotu, kterou chcete předat, je poslán jako další argument.,
longerSummary.call(book, 'dystopian', 1932)
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."
Pokud se pokusíte odeslat přesně stejné argumenty, s apply
, to je to, co se stane:
longerSummary.apply(book, 'dystopian', 1932)
Uncaught TypeError: CreateListFromArrayLike called on non-object at <anonymous>:1:15
Místo apply
, budete muset projít všechny argumenty v poli.
longerSummary.apply(book, )
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."
rozdíl mezi předáním argumentů jednotlivě nebo v poli je jemné, ale důležité je být si vědom., Může být jednodušší a pohodlnější používat apply
, protože by nevyžadovalo změnu volání funkce, pokud by se změnily některé detaily parametrů.
Vázat
call
apply
jsou na jedno použití metody—pokud budete volat metodu s this
souvislosti to bude mít, ale původní funkce zůstane beze změny.,
Někdy, možná budete muset použít metodu znovu a znovu s this
souvislosti jiný objekt, a v tomto případě můžete použít bind
způsob, jak vytvořit zcela nové funkce s explicitně vázán this
.
const braveNewWorldSummary = summary.bind(book)braveNewWorldSummary()
"Brave New World was written by Aldous Huxley"
V tomto příkladu, pokaždé, když budete volat braveNewWorldSummary
, to bude vždy vrátit původní this
hodnota vázán na to., Se snaží svázat nový this
souvislosti se nezdaří, takže můžete vždy věřit vázané funkce vrátí this
hodnoty, které očekáváte.
i když se tento příklad pokouší znovu vázatbraveNewWorldSummary
, zachovává původníthis
kontext od prvního okamžiku, kdy byl vázán.
Šipka Funkce
Šipka funkce nemají vlastní this
závazné. Místo toho jdou až na další úroveň popravy.,
může být užitečné použít funkci šipky v případech, kdy opravdu chcete this
odkazovat na vnější kontext. Například, pokud jste měli posluchače událostí uvnitř třídy, pravděpodobně byste chtěli this
odkazovat na určitou hodnotu ve třídě.
v tomto příkladu vytvoříte a připojíte tlačítko k DOM jako dříve, ale třída bude mít posluchače událostí, který po kliknutí změní textovou hodnotu tlačítka.
Pokud kliknete na tlačítko, textový obsah se změní na hodnotu buttonText
., Kdyby jsi nepoužil šíp funkce, this
se bude rovnat event.currentTarget
, a nebudete moci použít pro přístup k hodnotě v rámci třídy, aniž by výslovně závazné. Tato taktika se často používá na třídních metodách v rámcích, jako je React.
Závěr
V tomto článku, jste se dozvěděli o this
v Javascriptu, a mnoho různých hodnot může mít na základě implicitní runtime závazné, a explicitní vazba přes bind
call
apply
., Také jste se dozvěděli, jak může být nedostatek vazby this
ve funkcích se šipkami použit k označení jiného kontextu. S těmito znalostmi byste měli být schopni určit hodnotu this
ve vašich programech.