Co přesně v JavaScriptu znamená klíčové slovo this
? Jak jej můžeme efektivně využít při programování? To jsou otázky, které si často kladou začátečníci, a dokonce i zkušení vývojáři. Klíčové slovo this
může být pro mnohé matoucí.
Pokud i vy patříte k těm, které toto téma zajímá, pak je tento článek určen přímo vám. Společně prozkoumáme jeho význam v různých kontextech a upozorníme na potenciální problémy, abyste se vyhnuli nejasnostem a chybám v kódu.
this
v globálním kontextu
Pokud se nacházíme v globálním kontextu, mimo jakoukoliv funkci, this
odkazuje na objekt window
. Globální kontext znamená, že klíčové slovo this
nepoužíváte uvnitř žádné funkce.
if(true) { console.log(this) } let i = 2 while(i < 10) { console.log(this) i++ }
Při spuštění výše uvedeného kódu získáte jako výstup objekt window
.
this
uvnitř funkcí (metod)
V případě použití this
uvnitř funkcí, odkazuje na objekt, ke kterému je daná funkce vázána. Jedinou výjimkou je situace, kdy this
použijete v samostatné funkci. V takovém případě se this
opět stává odkazem na objekt window
. Projděme si několik příkladů.
V následujícím kódu je funkce sayName
definována uvnitř objektu me
(tj. jedná se o metodu). V takových situacích this
odkazuje na objekt, který danou funkci obsahuje.
function sayName() { return `Moje jméno je ${this.name}` } const me = { name: "Kingsley", sayName: sayName } console.log(me.sayName())
Zde this
reprezentuje objekt me
, a proto this.name
uvnitř metody sayName
je ekvivalentní me.name
.
Další způsob, jak si to představit, je, že cokoliv se nachází nalevo od volané funkce, se stává hodnotou this
. To znamená, že funkci sayName
můžeme znovu použít i v jiných objektech, a this
bude pokaždé odkazovat na jiný kontext.
Jak už bylo zmíněno, v případě samostatné funkce, this
vrací objekt window
. Je to proto, že samostatná funkce je standardně asociována s objektem window
:
function talk() { return this } talk()
Volání talk()
je ekvivalentní volání window.talk()
, a tak se cokoliv nalevo od funkce automaticky stává this
.
Je také důležité zmínit, že chování this
ve funkcích se liší v přísném režimu JavaScriptu (vrací undefined
). To je důležitý fakt, pokud používáte například knihovny uživatelského rozhraní, které přísný režim používají (např. React).
Použití this
s funkcí Function.bind()
Někdy nemusíte mít možnost jen tak přidat funkci k objektu jako metodu (jak bylo ukázáno dříve).
Možná daný objekt není váš, a čerpáte ho z knihovny. Nebo je objekt neměnný a nemůžete ho přímo upravovat. V takových případech můžeme s výhodou využít metodu Function.bind()
.
V následujícím příkladu funkce sayName
není metodou objektu me
, ale přesto ji svážeme pomocí bind()
:
function sayName() { return `Moje jméno je ${this.name}` } const me = { name: "Kingsley" } const meTalk = sayName.bind(me) meTalk()
Objekt, který předáme metodě bind()
, se použije jako hodnota this
pro volání této funkce.
Zjednodušeně, můžeme použít bind()
na jakoukoli funkci a předat nový kontext (objekt), který přepíše význam this
uvnitř dané funkce.
Použití this
s funkcí Function.call()
Co když nechcete vracet novou funkci, ale raději ji chcete rovnou zavolat po navázání na daný kontext? Pak použijeme metodu call()
:
function sayName() { return `Moje jméno je ${this.name}` } const me = { name: "Kingsley" } sayName.call(me)
Metoda call()
okamžitě provede funkci namísto vracení jiné funkce.
Pokud funkce vyžaduje parametry, můžeme je předat pomocí call()
. Následující příklad předává jazyk do funkce sayName()
, abychom mohli podmíněně vracet různé zprávy:
function sayName(lang) { if (lang === "en") { return `Moje jméno je ${this.name}` } else if (lang === "it") { return `Io sono ${this.name}` } } const me = { name: "Kingsley" } sayName.call(me, 'en') sayName.call(me, 'it')
Jak vidíte, můžeme funkci předat libovolný parametr jako další argument metody call()
. Počet parametrů není omezen.
Metoda apply()
je velmi podobná metodám call()
a bind()
. Hlavním rozdílem je, že zatímco v call()
předáváme parametry oddělené čárkami, v apply()
je předáváme uvnitř pole.
Stručně řečeno, bind()
, call()
a apply()
umožňují volat funkce s naprosto jiným objektem, i když mezi nimi není žádný vztah (tj. funkce není metodou na objektu).
this
uvnitř konstruktorů
Při volání funkce s klíčovým slovem new
, se vytvoří nový objekt this
, a ten se následně vrátí:
function person(name){ this.name = name } const me = new person("Kingsley") const her = new person("Sarah") const him = new person("Jake") me.name her.name him.name
V kódu výše jsme vytvořili tři různé objekty ze stejné funkce. Klíčové slovo new
automaticky vytvoří vazbu mezi vytvářeným objektem a this
uvnitř funkce.
this
uvnitř zpětných volání
Zpětná volání se chovají trochu jinak než klasické funkce. Zpětné volání je funkce, kterou předáváme jiné funkci jako argument a která se má provést po dokončení hlavní funkce.
V případě zpětných volání se this
chová odlišně:
function person(name){ this.name = name setTimeout(function() { console.log(this) }, 1000) } const me = new person("Kingsley")
Po jedné sekundě od volání konstruktoru person
a vytvoření nového objektu me
, se jako hodnota this
zaloguje objekt window
. Tedy v tomto případě this
odkazuje na objekt window
, a ne na „vytvořený“ objekt.
Existují dva způsoby, jak to vyřešit. První metoda využívá bind()
k navázání funkce person na nově vytvořený objekt:
function person(name){ this.name = name setTimeout(function() { console.log(this) }.bind(this), 1000) } const me = new person("Kingsley")
Po této úpravě, this
ve zpětném volání bude odkazovat na stejný objekt jako uvnitř konstruktoru (objekt me
).
Druhým způsobem, jak vyřešit problém s this
ve zpětných voláních, je použití arrow funkcí.
this
uvnitř arrow funkcí
Arrow funkce (funkce šipky) se liší od klasických funkcí. Můžeme tedy zpětné volání změnit na arrow funkci. S arrow funkcemi již bind()
nepotřebujeme, protože se automaticky váží na nově vytvořený objekt:
function person(name){ this.name = name setTimeout(() => { console.log(this) }, 1000) } const me = new person("Kingsley")
Další informace o JavaScriptu
V tomto článku jste se dozvěděli o klíčovém slově this
a o jeho významu v různých kontextech JavaScriptu. Pokud s JavaScriptem začínáte, je důležité naučit se všechny jeho základy a porozumět tomu, jak funguje. Věřím, že tyto informace vám pomohou lépe pracovat s JavaScriptem.