Úvod
Dovolte mi začít tento článek poděkováním čtenářům mé série JavaScript:Cracking the Nuts za to, že se jim zatím líbí a milují. Tento článek se bude zabývat dalším základním, ale stejně nepochopeným aspektem JavaScriptu, který se nazývá this
klíčové slovo.
Dobře, tak začneme. Na konci článku byste měli lépe rozumět,
- Co je toto v JavaScriptu.
- Jak to udělat to zní méně zmateně než kdy jindy.
- Pravidla tohoto a použití.
- Důležité, toto je snadné!
Upozornění na dlouhé čtení ⚠️
Na rozdíl od jiných článků ze série bude tento trochu zdlouhavý. Po prostudování několika tutoriálů jsem cítil, že je třeba propojit různé aspekty, abychom pochopili koncept this
studna. Například koncept call => apply => bind
velmi souvisí s porozuměním this
klíčové slovo. Musíme je spolu probrat.
Mohl jsem věci rozdělit do více článků, ale je lepší být spolu, protože pojmy jsou velmi propojené. Proto to dlouhé upozornění na čtení!
Vezměte si své oblíbené nápoje, odpočiňte si a začněte číst. Jsem si jistý, že si to užijete.
Co je this
?
this
je klíčové slovo v JavaScriptu a jeho existence nám umožňuje vstoupit,
- Chápat různé kontexty provádění.
- Kontext objektu, který
this
souvisí s.
Pamatujte, že když je kontext spuštění vytvořen v JavaScriptu, vytvoří se speciální věc s názvem this
.
- V kontextu globálního provádění toto je rovno globálnímu
window
objekt. - V kontextu provádění funkce hodnota toto závisí na
binding
.
Pravidla vázání
Porozumět this
funkce může být náročné klíčové slovo, protože se v JavaScriptu chová jinak než v jiných jazycích. Pokud jde o nalezení kontextu this
, musíme vidět, kde je funkce vyvolána.
Použití this
lze rozdělit do čtyř různých závazných aspektů.
Implicitní vazba
Implicitní vazba je nejpoužívanějším případem použití this
klíčové slovo. Když vyvoláme metodu objektu, použijeme pro přístup k němu notaci tečka(.). V případě implicitní vazby kontext this
je vázán na objekt, na kterém metodu vyvoláme.
Zde je příklad
Příklad:
const user = {
name: 'GreenRoots',
address: 'HashNode',
greeting: function() {
return `Hello, ${this.name} belongs to ${this.address}`
}
};
user.greeting();
Vysvětlení: Ve výše uvedeném příkladu vyvoláme greeting()
metoda na objektu uživatele pomocí notace tečka(.). Proto this
je vázán na objekt uživatele. Takže this.name
se chystá přihlásit GreenRoots
a this.address
je HashNode
.
Vezměme si další příklad pro lepší vysvětlení tohoto konceptu,
Příklad:
function greeting(obj) {
obj.logMessage = function() {
console.log(`${this.name} is ${this.age} years old!`);
}
};
const tom = {
name: 'Tom',
age: 7
};
const jerry = {
name: 'jerry',
age: 3
};
greeting(tom);
greeting(jerry);
tom.logMessage ();
jerry.logMessage ();
Vysvětlení: Ve výše uvedeném příkladu máme dva objekty, tom
a jerry
. Tyto objekty jsme ozdobili (vylepšili) připojením metody nazvané logMessage ()
.
Jen si všimněte, když voláme tom.logMessage()
, metoda je vyvolána na tom
objekt. Proto this
vázaný na tom
objekt. Totéž platí, když jerry.logMessage ()
je vyvoláno.
Explicitní vazba
Jsme si vědomi toho, že JavaScript vytváří prostředí pro provádění kódu, který píšeme. Toto prostředí obsahuje věci nad rámec skutečného kódu, který píšeme.
Stará se o vytvoření paměti pro proměnné, funkce, objekty atd. ve fázi vytváření. Nakonec spusťte kód ve fázi provádění. Toto speciální prostředí se nazývá JavaScript Execution Context
.
Existuje mnoho takových prostředí (kontexty provádění) v aplikaci JavaScript. Každý kontext provádění je nezávislý na druhém. Ale můžeme chtít získat přístup k něčemu z jednoho kontextu provádění do druhého. Zde vstupuje do hry explicitní vazba. Pomocí toho můžeme svázat věci z jednoho kontextu do kontextu jiného prostředí .
Existují tři mimořádné metody, call()
, apply()
a bind()
, pomůže dosáhnout explicitní vazby.
metoda call()
U metody call() bude kontext, se kterým má být funkce volána, předán jako parametr call(). Podívejme se na příklad
Příklad:
greeting: function() {
return `Hello, ${this.name} belongs to ${this.address}`
}
const user = {
name: 'GreenRoots',
address: 'HashNode'
};
greeting.call(user);
Vysvětlení: Zde vidíme, že metoda call() je vyvolána ve funkci zvané greeting(). Funkce greeting() pouze zaprotokoluje zprávu pomocí this.name
a this.address
. Ale co je this
tady? To je určeno tím, co bylo předáno metodě call().
Zde this
se naváže na objekt uživatele, protože jsme předali uživatele jako parametr metodě call(). Proto this.name
by měl zaznamenat hodnotu vlastnosti názvu objektu uživatele, tj. GreenRoots a podobně, this.address
jako Hashnode.
Ve výše uvedeném příkladu jsme předali pouze jeden argument pro call(). V případě potřeby však můžeme volání call() předat více argumentů. Vezměme si další příklad, abychom to pochopili,
Příklad
var getName = function(hobby1, hobby2) {
console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2);
}
var user = {
name: 'Tapas',
address: 'Bangalore'
};
var hobbies = ['Swimming', 'Blogging'];
getName.call(user, hobbies[0], hobbies[1]);
Vysvětlení: Všimněte si, že jsme zde předali další dva argumenty v metodě call(). Prvním argumentem musí být kontext objektu, se kterým má být funkce vyvolána. Ostatní parametry mohou být pouze hodnoty, které se mají použít. Zde míjím Plavání a Blogování jako dva parametry funkce getName().
Všimli jste si bodu bolesti? V případě call() je třeba argumenty předat jeden po druhém, což není tak chytrý způsob, jak věci dělat! Zde přichází na řadu naše další metoda apply().
metoda apply()
Hektický způsob předávání argumentů metodě call() lze vyřešit jinou alternativní metodou nazvanou apply(). Je to stejné jako call()
ale umožňuje předávání argumentů pohodlněji. Podívejte se,
Příklad
var getName = function(hobby1, hobby2) {
console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2);
}
var user = {
name: 'Tapas',
address: 'Bangalore'
};
var hobbies = ['Swimming', 'Blogging'];
getName.apply(user, hobbies);
Vysvětlení: Jak vidíte zde, můžeme předat pole jako argumenty, což je mnohem pohodlnější než předávání jednoho po druhém.
metodabind()
call()
metoda vyvolá funkci předáním kontextu this
. bind()
metoda je podobná call()
ale místo přímého volání funkce bind() vrací zcela novou funkci, kterou můžeme místo toho vyvolat.
Příklad:
var getName = function(hobby1, hobby2) {
console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2);
}
var user = {
name: 'Tapas',
address: 'Bangalore'
};
var hobbies = ['Swimming', 'Blogging'];
var newFn = getName.bind(user, hobbies[0], hobbies[1]);
newFn();
Vysvětlení: Jak vidíme výše, getName.bind()
nevyvolá funkci getName(). Vrací novou funkci newFn, kterou můžeme vyvolat jako, newFn().
nová vazba
Funkce konstruktoru je vytvořena pomocí new
klíčové slovo. Zde je příklad funkce konstruktoru
var Cartoon = function(name, animal) {
this.name = name;
this.animal = animal;
this.log = function() {
console.log(this.name + ' is a ' + this.animal);
}
};
Objekty můžeme vytvořit pomocí new
klíčové slovo jako,
var tom = new Cartoon('Tom', 'Cat');
var jerry = new Cartoon('Jerry', 'Mouse');
Pojďme to rozebrat. Vezměte tento řádek,
var tom = new Cartoon('Tom', 'Cat');
Zde funkce Cartoon
se vyvolá pomocí new
klíčové slovo. Proto this
bude vázán na zde vytvořený nový objekt, tom
.
Vazba globálního objektu
Jaký bude výstup tohoto spuštění kódu? Co je this
svázat sem?
var sayName = function(name) {
// 'use strict';
console.log(this.name);
};
window.name = 'Tapas';
sayName();
pokud this
klíčové slovo není vyřešeno žádnou z výše uvedených vazeb, implicit
, explicit
nebo new
pak this
se váže k objektu window(global).
Funkce šipek, bez vazby?
ES6 zavedlo funkce šipek, které neposkytují vlastní this
vazba. Jak jsme doposud viděli, v běžných funkcích this
klíčové slovo představovalo objekt, který se nazývá funkce, což může být okno, dokument, uživatelsky definovaný nebo cokoli jiného.
Funkce šipek nesvazují svůj vlastní rozsah, ale zdědí jej od rodiče.
Příklad času. Uvidíme, jak to funguje.
var testHobbies = {
hobbies: ['Cricket', 'Football', 'Blogging'],
name: 'Alex',
logHobbies() {
this.hobbies.forEach((elem) => {
console.log(`${this.name} knows ${elem}`);
});
}
}
Zde metoda logHobbies() iteruje koníčky a přihlásí je do konzole. Všimněte si, že v forEach
používáme funkci šipky . this
uvnitř funkce šipky by se vázalo na objekt testHobbies
protože neexistuje this
vazba pro funkce šipky a vždy se váže k nadřazené.
Vyvolání testHobbies.logHobbies() by se tedy správně zaprotokolovalo jako,
Alex knows Cricket
Alex knows Football
Alex knows Blogging
Nyní do toho vneseme zvrat. Všimněte si úpravy, kterou jsem provedl níže. Místo funkce šipky používá for-each běžnou funkci.
var testHobbies = {
hobbies: ['Cricket', 'Football', 'Blogging'],
name: 'Alex',
logHobbies() {
this.hobbies.forEach(function(elem){
console.log(`${this.name} knows ${elem}`);
});
}
}
Co myslíte, this
by bylo vázáno sem uvnitř forEach? Není to funkce šipky. Je to běžná funkce a má svůj vlastní kontext provádění. V tomto kontextu provádění neexistuje nic, co by se nazývalo jméno. Proto this.name
není definováno.
Výstup tedy bude,
undefined knows Cricket
undefined knows Football
undefined know Blogging
Podrobněji to uvidíme v budoucích článcích na Scope
a Closure
.
Použít Strict a toto
Normálně v globálním rozsahu this
klíčové slovo odkazuje na objekt okna,
<script>
console.log(this); //returns window object.
</script>
V přísném režimu JavaScript také this
klíčové slovo v globálním rozsahu vrátí objekt okna. V rozsahu funkcí se však chová jinak.
Viz následující příklad
<script>
"use strict;"
console.log(this);
function testThis() {
"use strict";
console.log('testThis', this);
}
testThis();
</script>
Do konzole zaprotokoluje následující výstup
Window {parent: Window, opener: null, top: Window, length: 0, frames: Window, …}
testThis undefined
Závěr
Ano, rozumím this
je lehké! Ale zároveň může být náročné pochopit pravidla a použití this
. Budeme rozumět this
lépe, když se zaměříme na otázku, Where is the function invoked
?
Ve většině případů by použití bylo s implicitní vazbou. Bude použito s explicitní vazbou s call(), apply() a bind(). S mnoha frameworky založenými na JavaScriptu, jako je Reactjs, Angular atd., používáme funkce šipek.
Nezapomeňte, že pokud budete těmto pravidlům rozumět a budete je praktikovat, jistě budete souhlasit s tím, že this
je opravdu snadné pracovat!
Kredity a zdroje
- Krátké video YouTube od uidotdev
- Stránky MDN o
this
. - Titulní fotka je postavena na úžasném obrázku vytvořeném brgfx na freepik.
Další užitečné zdroje na this
- Co je to v JavaScriptu
- Jak v Javascriptu využít váš „tento“ kontext
Doufám, že vám článek bude užitečný. Lajkujte/sdílejte, ať se to dostane i k ostatním. Pokud se vám tento článek líbil nebo vám pomohl, pojďme se připojit. Najdete mě na Twitteru (@tapasadhikary), kde sdílím myšlenky, tipy a praktiky kódování.
Chcete-li dostávat e-mailová upozornění na mé nejnovější příspěvky, přihlaste se k odběru na můj blog kliknutím na tlačítko Odebírat v horní části stránky.
Vysvětlím další základní pojmy zvané Scope
a Closure
v budoucích příspěvcích seriálu. Zůstaňte naladěni.