Obvyklá syntaxe {...} nám umožÅuje vytvoÅit jeden objekt. Äasto vÅ¡ak potÅebujeme vytvoÅit mnoho podobných objektů, napÅ. vÃce uživatelů, položek menu a podobnÄ.
To můžeme uÄinit pomocà konstruktorů a operátoru "new".
Konstruktor
Konstruktory jsou z technického hlediska obvyklé funkce. Platà pro nÄ vÅ¡ak dvÄ konvence:
- Jejich název zaÄÃná velkým pÃsmenem.
- MÄly by být volány jen pomocà operátoru
ânewâ.
NapÅÃklad:
function Uživatel(jméno) {
this.jméno = jméno;
this.jeSprávce = false;
}
let uživatel = new Uživatel("Kuba");
alert(uživatel.jméno); // Kuba
alert(uživatel.jeSprávce); // false
Když je funkce volána pomocà new, provedou se následujÃcà kroky:
- VytvoÅà se nový prázdný objekt a pÅiÅadà se do
this. - Vykoná se tÄlo funkce. To obvykle modifikuje
this, do nÄhož pÅidá nové vlastnosti. - Vrátà se hodnota
this.
Jinými slovy, new Uživatel(...) udÄlá nÄco jako:
function Uživatel(jméno) {
// this = {}; (implicitnÄ)
// pÅidá vlastnosti do this
this.jméno = jméno;
this.jeSprávce = false;
// return this; (implicitnÄ)
}
Takže let uživatel = new Uživatel("Kuba") vydá stejný výsledek jako:
let uživatel = {
jméno: "Kuba",
jeSprávce: false
};
Když nynà budeme chtÃt vytvoÅit jiné uživatele, můžeme volat new Uživatel("Anna"), new Uživatel("Alice") a tak dále. Je to mnohem kratšà než pokaždé použÃvat literály a je to i snadno Äitelné.
To je hlavnà smysl konstruktorů â implementovat opakovanÄ použitelný kód pro vytváÅenà objektů.
Znovu poznamenejme, že technicky může být libovolná funkce (s výjimkou Å¡ipkových funkcÃ, jelikož ty nemajà this) použita jako konstruktor. Může být volána pomocà new a pak se vykoná výše uvedený algoritmus. âVelké prvnà pÃsmenoâ je obvyklá úmluva, aby bylo zÅejmé, že funkce má být volána pomocà new.
Máme-li mnoho Åádků kódu a vÅ¡echny se týkajà vytvoÅenà jediného složitého objektu, můžeme je zapouzdÅit do konstruktoru, který okamžitÄ zavoláme, napÅÃklad:
// vytvoÅÃme funkci a okamžitÄ ji zavoláme pomocà new
let uživatel = new function() {
this.jméno = "Jan";
this.jeSprávce = false;
// ...dalšà kód pro vytváÅenà uživatele
// možná složitá logika a pÅÃkazy
// lokálnà promÄnné atd.
};
Tento konstruktor nemůžeme volat znovu, protože nenà nikde uložen, bude pouze vytvoÅen a zavolán. Smyslem tohoto triku je tedy zapouzdÅit kód, který vytvoÅà jediný objekt a dále se nepoužÃvá.
Test režimu konstruktoru: new.target
Syntaxe z této Äásti se použÃvá málokdy. Pokud nechcete znát opravdu vÅ¡echno, můžete ji pÅeskoÄit.
UvnitÅ funkce můžeme ovÄÅit, zda byla volána pomocà new nebo bez nÄj, pomocà speciálnà vlastnosti new.target.
Ta je pÅi bÄžném volánà undefined, ale pokud je funkce volána pomocà new, je rovna této funkci:
function Uživatel() {
alert(new.target);
}
// bez ânewâ:
Uživatel(); // undefined
// s ânewâ:
new Uživatel(); // function Uživatel { ... }
Můžeme ji použÃt uvnitÅ funkce, abychom se dozvÄdÄli, zda byla volána âv režimu konstruktoruâ pomocà new nebo âv bÄžném režimuâ bez nÄj.
Můžeme také funkci pÅimÄt, aby pÅi volánà pomocà new a pÅi bÄžném volánà provádÄla totéž, napÅÃklad takto:
function Uživatel(jméno) {
if (!new.target) { // pokud mÄ spustÃte bez new
return new Uživatel(jméno); // ...pÅidám new pro vás
}
this.jméno = jméno;
}
let jan = Uživatel("Jan"); // pÅesmÄruje volánà na new Uživatel
alert(jan.jméno); // Jan
Tento pÅÃstup se nÄkdy použÃvá v knihovnách, aby byla syntaxe flexibilnÄjÅ¡Ã. Lidé pak mohou volat funkci s new nebo bez nÄj a funkce pokaždé funguje.
PravdÄpodobnÄ vÅ¡ak nenà dobré použÃvat jej vÅ¡ude, protože bez uvedenà new je trochu ménÄ zÅejmé, co se dÄje. Když je uvedeno new, vÅ¡ichni vÃme, že se vytváÅà nový objekt.
Návrat z konstruktorů
Konstruktory obvykle nemajà pÅÃkaz return. Jejich úkolem je zapsat vÅ¡echno potÅebné do this a to se pak automaticky stane výsledkem.
Jestliže vÅ¡ak je pÅÃkaz return pÅÃtomen, platà jednoduché pravidlo:
- Je-li
returnvolán s objektem, vrátà se namÃstothistento objekt. - Je-li
returnvolán s primitivem, tento primitiv se ignoruje.
Jinými slovy, return s objektem vrátà onen objekt, ve vÅ¡ech ostatnÃch pÅÃpadech se vrátà this.
NapÅÃklad zde return pÅepisuje this vrácenÃm objektu:
function VelkýUživatel() {
this.jméno = "Jan";
return { jméno: "Godzilla" }; // <-- vrátà tento objekt
}
alert( new VelkýUživatel().jméno ); // Godzilla, zÃskali jsme onen objekt
A zde je pÅÃklad s prázdným return (nebo za nÄj můžeme umÃstit primitiv, na tom nezáležÃ):
function MalýUživatel() {
this.jméno = "Jan";
return; // <-- vrátà this
}
alert( new MalýUživatel().jméno ); // Jan
Konstruktory obvykle pÅÃkaz return neobsahujÃ. Speciálnà chovánà s vracenÃm objektů zde zmiÅujeme zejména pro úplnost.
Mimochodem, závorky za new můžeme vypustit:
let uživatel = new Uživatel; // <-- bez závorek
// totéž jako
let uživatel = new Uživatel();
VypouÅ¡tÄnà závorek zde se nepovažuje za âdobrý stylâ, ale specifikace tuto syntaxi povoluje.
Metody v konstruktoru
PoužÃvánà konstruktorů k vytváÅenà objektů nám dává velké množstvà flexibility. Konstruktor může mÃt parametry, které definujÃ, jak objekt zkonstruovat a co do nÄj uložit.
SamozÅejmÄ do this můžeme pÅidávat nejen vlastnosti, ale také metody.
NapÅÃklad nÞe uvedené new Uživatel(jméno) vytvoÅà objekt se zadanou vlastnostà jméno a metodou ÅekniAhoj:
function Uživatel(jméno) {
this.jméno = jméno;
this.ÅekniAhoj = function() {
alert( "Jmenuji se: " + this.jméno );
};
}
let jan = new Uživatel("Jan");
jan.ÅekniAhoj(); // Jmenuji se: Jan
/*
jan = {
jméno: "Jan",
ÅekniAhoj: function() { ... }
}
*/
K vytváÅenà složitých objektů existuje i pokroÄilejšà syntaxe â tÅÃdy, kterou probereme pozdÄji.
ShrnutÃ
- Konstruktory jsou obvyklé funkce, avÅ¡ak panuje bÄžná úmluva, že jejich název by mÄl mÃt velké prvnà pÃsmeno.
- Konstruktory by mÄly být volány jedinÄ pomocÃ
new. Takové volánà způsobÃ, že se na zaÄátku vytvoÅà prázdnéthisa to se pak na konci vrátà naplnÄné.
Konstruktory můžeme použÃvat k vytváÅenà vÃce podobných objektů.
JavaScript poskytuje konstruktory pro mnoho vestavÄných jazykových objektů: napÅ. Date pro data, Set pro množiny a jiné, které máme v plánu prostudovat.
V této kapitole probÃráme ohlednÄ objektů a konstruktorů jen základy, které jsou podstatné pro pochopenà dalÅ¡Ãch vÄcà ohlednÄ datových typů a funkcà v dalÅ¡Ãch kapitolách.
Až se je nauÄÃme, vrátÃme se k objektům a probereme je do hloubky v kapitolách Prototypy, dÄdiÄnost a TÅÃdy.
KomentáÅe
<code>, pro nÄkolik Åádků je obalte znaÄkou<pre>, pro vÃce než 10 Åádků vložte odkaz na pÃskoviÅ¡tÄ (plnkr, jsbin, codepenâ¦)