toto v JavaScriptu. Jediný článek, který si musíte přečíst.

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.