Pochopení JavaScriptového klíčového slova „toto“.

Co znamená toto klíčové slovo v JavaScriptu? A jak jej můžete prakticky využít ve svém JavaScript programu? To jsou některé z běžných otázek, které se nováčci a dokonce i někteří zkušení vývojáři JavaScriptu ptají na klíčové slovo this.

Pokud jste jedním z těch vývojářů, kteří se zajímají o to, o čem toto klíčové slovo je, pak je tento článek určen právě vám. Prozkoumejte, co to znamená v různých kontextech, a seznamte se s některými problémy, abyste se vyhnuli zmatkům a samozřejmě chybám ve vašem kódu.

„toto“ uvnitř globálního rozsahu

V globálním kontextu to vrátí objekt okna, pokud je mimo funkci. Globální kontext znamená, že jej nevkládáte do funkce.

 if(true) {
  console.log(this)
}

let i = 2
while(i < 10) {
  console.log(this)
  i++
}

Pokud spustíte výše uvedený kód, získáte objekt okna.

„toto“ vnitřní funkce (metody)

Při použití uvnitř funkcí se to týká objektu, ke kterému je funkce vázána. Výjimkou je případ, kdy to použijete v samostatné funkci, v takovém případě vrátí objekt okna. Podívejme se na několik příkladů.

V následujícím příkladu je funkce sayName uvnitř objektu me (tj. je to metoda). V případech, jako je tento, to odkazuje na objekt obsahující funkci.

  
function sayName() {
  return `My name is ${this.name}`
}

const me = {
  name: "Kingsley",
  sayName: sayName
}

console.log(me.sayName())

toto je objekt me, takže vyslovení tohoto.jméno v metodě sayName je úplně stejné jako me.jméno.

  Použijte Smartsheet k automatizaci procesů, správě projektů a sledování úloh

Jiný způsob, jak si to představit, je, že cokoli je při vyvolání na levé straně funkce, bude toto. To znamená, že funkci sayName můžete znovu použít v různých objektech, což bude pokaždé odkazovat na úplně jiný kontext.

Nyní, jak již bylo zmíněno, toto vrací objekt okna při použití uvnitř samostatné funkce. Je to proto, že samostatná funkce je standardně svázána s objektem okna:

 function talk() {
  return this
}

talk()

Volání talk() je stejné jako volání window.talk() a cokoli, co je na levé straně funkce, se automaticky stane tímto.

Na okraj, klíčové slovo this ve funkci se v přísném režimu JavaScriptu chová jinak (vrací se nedefinováno). To je také něco, co je třeba mít na paměti, když používáte knihovny uživatelského rozhraní, které používají přísný režim (např. React).

Použití „toto“ pomocí Function.bind()

Mohou existovat scénáře, kdy nemůžete pouze přidat funkci k objektu jako metodu (jako v poslední části).

Možná ten předmět není váš a vy ho vytahujete z knihovny. Objekt je neměnný, takže ho nemůžete jen tak změnit. V případech, jako je tento, můžete stále provádět příkaz funkce odděleně od objektu pomocí metody Function.bind().

V následujícím příkladu funkce sayName není metodou na objektu me, ale přesto jste ji svázali pomocí funkce bind():

 function sayName() {
  return `My name is ${this.name}`
}

const me = {
  name: "Kingsley"
}

const meTalk = sayName.bind(me)

meTalk()

Jakýkoli objekt, který předáte do bind(), bude použit jako hodnota tohoto v tomto volání funkce.

  Jak P2E v vůbec první multiřetězové hře na světě

Stručně řečeno, můžete použít bind() na jakoukoli funkci a předat v novém kontextu (objekt). A tento objekt přepíše význam tohoto uvnitř této funkce.

Použití „toto“ pomocí Function.call()

Co když nechcete vrátit úplně novou funkci, ale raději funkci zavoláte poté, co ji navážete na její kontext? Řešením je metoda call():

 function sayName() {
  return `My name is ${this.name}`
}

const me = {
  name: "Kingsley"
}

sayName.call(me)

Metoda call() okamžitě provede funkci místo vracení jiné funkce.

Pokud funkce vyžaduje parametr, můžete jej předat pomocí metody call(). V následujícím příkladu předáváte jazyk funkci sayName(), takže ji můžete použít k podmíněnému vracení různých zpráv:

 function sayName(lang) {
  if (lang === "en") {
    return `My name is ${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ůžete funkci předat libovolný parametr, který chcete, jako druhý argument metody call(). Můžete také předat tolik parametrů, kolik chcete.

Metoda apply() je velmi podobná metodám call() a bind(). Jediný rozdíl je v tom, že předáte více argumentů tak, že je oddělíte čárkou pomocí call(), zatímco více argumentů předáte uvnitř pole pomocí apply().

Stručně řečeno, bind(), call() a apply() vám umožňují volat funkce s úplně jiným objektem, aniž by mezi nimi existoval jakýkoli vztah (tj. funkce není metodou na objektu).

„toto“ uvnitř funkcí konstruktoru

Pokud zavoláte funkci s novým klíčovým slovem, vytvoří objekt this a vrátí jej:

 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

Ve výše uvedeném kódu jste vytvořili tři různé objekty ze stejné funkce. Klíčové slovo new automaticky vytvoří vazbu mezi vytvářeným objektem a klíčovým slovem this uvnitř funkce.

  Zobrazení a porovnání verzí příloh ve vláknech Gmailu [Chrome]

„toto“ uvnitř funkcí zpětného volání

Funkce zpětného volání se liší od běžných funkcí. Funkce zpětného volání jsou funkce, které předáváte jiné funkci jako argument, takže je lze spustit ihned poté, co se hlavní funkce dokončí.

Klíčové slovo this odkazuje při použití uvnitř funkcí zpětného volání na zcela odlišný kontext:

 function person(name){
  this.name = name
  setTimeout(function() {
    console.log(this)
  }, 1000)
}

const me = new person("Kingsley")

Po jedné sekundě volání funkce konstruktoru osoby a vytvoření nového objektu me zaznamená objekt okna jako hodnotu tohoto. Takže při použití ve funkci zpětného volání to odkazuje na objekt okna a ne na „konstruovaný“ objekt.

Existují dva způsoby, jak to opravit. 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")

S výše uvedenou úpravou to ve zpětném volání bude ukazovat na totéž jako funkce konstruktoru (objekt me).

Druhým způsobem, jak tento problém vyřešit ve funkcích zpětného volání, je použití funkcí šipek.

„toto“ uvnitř funkcí šipky

Funkce šipek se liší od běžných funkcí. Funkci zpětného volání můžete změnit na funkci šipky. S funkcemi šipek již nepotřebujete bind(), protože se automaticky váže k nově vytvořenému objektu:

 function person(name){
  this.name = name
  setTimeout(() => {
    console.log(this)
  }, 1000)
}

const me = new person("Kingsley")

Zjistěte více o JavaScriptu

Dozvěděli jste se vše o klíčovém slově „toto“ a o tom, co znamená ve všech různých kontextech JavaScriptu. Pokud s JavaScriptem začínáte, budete mít velký užitek z toho, že se naučíte všechny základy JavaScriptu a jak funguje.