Pokud jste jako já, strávili jste několik hodin snahou pochopit to . Slyšeli jste pojmy jako, funkce váže své vlastní toto a ty jsi to nepochopil. Byl jsem tam, proto píšu tento článek. Cílem je pomoci vám porozumět konceptu jednoduchým a jasným způsobem.
Tento článek je zaměřen na následující skupiny:
• juniorní vývojáři
• seniorní vývojáři
Předpokladem požadovaných znalostí jsou následující:
• Funkce v JavaScriptu
• Pochopení objektu okna
• Syntaxe třídy v JavaScriptu
• Objekty v JavaScriptu
• Posluchače událostí v JavaScriptu
Tento článek nepokrývá pokročilé okrajové případy klíčového slova this, přečtěte si prosím dokumenty zde:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this.
Článek se skládá ze dvou částí:
Část 1 pojednává o každodenním použití tohoto:
• co je to
• toto v běžných funkcích
Část 2 zahrnuje následující:
• toto ve funkcích šipek
• toto ve zvláštních případech
Co je this
? this
je speciální klíčové slovo v JavaScriptu. Vždy bez výjimky odkazuje na objekt . Takže máme vyřešenou první část, toto je ukazatel v JavaScriptu. Jdeme dál. Druhá část, toto je vždy deklarováno ve funkci . To je klíč k pochopení this
. Pro přehlednost jsou zde opět pravidla:
• toto je vždy ukazatel na objekt.
• toto je vždy definováno uvnitř funkce.
Podívejme se na rychlý příklad:
let obj = {
country : 'nigeria',
getCountry(){
return this.country;
}
};
Nedělejte si starosti s kódem, bude vysvětlen, jen dodržujte this
je ve funkci a odkazuje na objekt- obj
.
Běžné funkce (pro zjednodušení budou odkazovat na jakoukoli jinou funkci než funkce šipky) a this
. Přečtěte si pozorně zde. Když this
je definována v běžné funkci, ukazuje na objekt, který funkci vyvolává. Jinými slovy, ukazuje na objekt, který volal funkci. To znamená, že this
v běžné funkci si NENÍ jistý, na co má ukazovat, dokud není funkce vyvolána. Zvažte jednoduchý příklad výše:
• Funkce uvnitř objektu, jako je tato, se nazývá metoda.
• this
v getCountry
Funkce zatím neví, na jaký objekt má ukázat, je stejně zmatená jako vy a já.
• hodnota this
se stane pro JavaScript jasný, když funkci vyvoláte (spustíte nebo zavoláte).
• hodnota this
, je nastaven na objekt, který přímo volá funkci.
• Chcete-li tedy zavolat getCountry
metoda, píšeme:
obj.getCountry();
• Hádejte, čeho se to týká.
• Ano, odkazuje na obj
objekt, protože to byl objekt, který volal funkci getCountry.
• Výstup tedy bude:nigérie.
Podívejme se na něco zajímavějšího. Na základě následujících výrazů určete výstup a vysvětlete proč. Zkuste to sami, než uvidíte moje vysvětlení.
First example:
function logger(str){
return this.str;
}
logger(‘John’) // ??
Second example:
let obj = {
name : 'John',
getName(){
function anotherFunc(){
return this.name;
}
return anotherFunc();
}
}
obj.getName() // ??
jak to dopadlo? Nezáleží na tom, jak dlouho ses snažil. Nyní se podívejme na první příklad:
• Když zavoláte funkci, logger
, co se stane?
• Všechny funkce JavaScriptu běží v zákulisí objektu. Tento objekt je označován jako kontext funkce .
• Malý trik, jak určit kontext funkce, je podívat se nalevo od funkce, když je vyvolána.
• this
vždy odkazuje na kontext.
• Volání logger
funkce, zapíšeme logger();
• Ve skutečnosti se děje toto:window.logger();
• Důvodem je window
objekt je nejbližší objekt k funkci, proto je jejím kontextem.
• Funkce zaznamená undefined
, jako str
vlastnost na objektu okna neexistuje.
• Pokud odstraníme str
parametr z funkce a stačí vrátit this
, získáte window
objekt.
V tomto druhém příkladu pro přístup k getName
metodou, zapíšeme obj.getName()
,ale dostaneme undefined
jako náš výsledek. To se děje, protože naše metoda vrací jinou funkci. Funkce vnořená do getName
metoda- vnořená funkce. Vnořená funkce je funkce s this
.
Co znamená this
ukázat na? No, zkusme zavolat vnořenou funkci a pak se podívejme doleva.
obj.getName.anotherFunc()
Jak vidíte, nejbližší volající z anotherFunc
funkce není objekt, ale metoda:getName
. Ale this
nikdy neukazuje na funkci. co se skutečně děje?
No, tohle je ono:
obj.getName.window.anotherfunc
Tedy objekt nejblíže anotherFunc
je okno.
Tento objekt nemá vlastnost name, takže vrací undefined
.
Tato logika platí pro všechny běžné funkce vnořené v metodě, bez ohledu na to, jak hluboké je vnoření, kontext je vždy objekt okna. Můžete si to vyzkoušet sami.
Dosud jsme diskutovali o některých klíčových konceptech, doporučuji vám procvičit si některé otázky, abyste si ověřili své porozumění.
Zkuste tyto dva (odpovědi jsou hned za oběma otázkami):
Question 1:
const object = {
message: 'Hello, World!',
getMessage() {
const message = 'Hello, Earth!';
return this.message;
}
};
console.log(object.getMessage()); // What is logged?
Question 2:
const object = {
message: 'Hello, World!'
};
function logMessage() {
console.log(this.message); //
}
logMessage(); // ??
Tyto otázky pocházejí od Dmitrije Pavlutina, více se můžete podívat na jeho blog zde:https://dmitripavlutin.com/javascript-this-interview-questions/
Odpověď na otázku 1:
Hello, World!
Odpověď na otázku 2:
undefined
Koncepty, o kterých jsme dosud diskutovali, jsou přirozené způsoby, jak to funguje. Tomu se říká implicitní vazba z toho. Někdy však chceme vynutit this
chovat se pružněji. Například v anotherFunc
výše, řekněme, že chceme this
do bodu obj
, spíše než window
objekt. No, musíme výslovně řekněte JavaScriptu, aby to udělal.
Explicitní této vazby lze dosáhnout jedním ze tří jednoduchých způsobů:
• call
(kontext, argument)
• apply
(kontext, [arg])
• bind
(kontext, argument)
Metoda volání se aplikuje na funkci za účelem změny kontextu funkce, tj. změny this
je ukazuje na. Můžeme to změnit na cokoliv chceme.
Chcete-li změnit anotherFunc
odkazovat na naše obj
objekt, přerámujeme náš objekt takto:
let obj = {
name : 'John',
getName(){
function anotherFunc(){
return this.name;
}
return anotherFunc.call(obj);
}
}
obj.getName() // "John"
Druhý parametr metody volání je args
, který odkazuje na argument, který chcete předat funkci. Zde je příklad:
function welcome(event){
return 'Hello ' + this.name + ' welcome to the ' + event
}
let obj = {
name : 'John'
}
welcome.call(obj,'Oscars'); //
'Hello John welcome to the Oscars'
Metoda Apply funguje přesně jako metoda volání, kromě toho trvá args
ve formě pole. Například:
function welcome(a, b, c){
console.log('Hello ' + this.name + ' welcome to the ' + a);
console.log('Hello ' + this.name + ' welcome to the ' + b);
console.log('Hello ' + this.name + ' welcome to the ' + c);
}
let obj = {
name : 'John'
}
let events = ['Grammy', 'Oscars', 'World cup'];
welcome.apply(obj, events);
// Hello John welcome to the Grammy
// Hello John welcome to the Oscars
// Hello John welcome to the World cup
//a, b, and c ---> the indices of the events elements.
Metoda bind funguje jako metoda volání, ale vrací novou funkci, kterou lze volat později. Například:
function welcome(event){
return 'Hello ' + this.name + ' welcome to the ' + event
}
let obj = {
name : 'John'
}
let bindFunc = welcome.bind(obj,'Oscars');
bindFunc(); //
'Hello John welcome to the Oscars'
Doufám, že tento článek vám to objasnil. Část 2 se zaměří na některé zvláštní části this
, zatím na zdraví a brzy na viděnou.