TÅÃdnà dÄdiÄnost je způsob, jak může jedna tÅÃda rozÅ¡ÃÅit jinou.
Můžeme tedy vytvoÅit novou funkcionalitu nad existujÃcÃ.
KlÃÄové slovo âextendsâ
ÅeknÄme, že máme tÅÃdu ZvÃÅe:
class ZvÃÅe {
constructor(jméno) {
this.rychlost = 0;
this.jméno = jméno;
}
bÄž(rychlost) {
this.rychlost = rychlost;
alert(`${this.jméno} bÄžà rychlostà ${this.rychlost}.`);
}
stůj() {
this.rychlost = 0;
alert(`${this.jméno} klidnÄ stojÃ.`);
}
}
let zvÃÅe = new ZvÃÅe("Moje zvÃÅe");
Graficky můžeme zobrazit objekt zvÃÅe a tÅÃdu ZvÃÅe takto:
â¦A rádi bychom vytvoÅili dalšà tÅÃdu KrálÃk.
Protože králÃci jsou zvÃÅata, tÅÃda KrálÃk by mÄla být založena na tÅÃdÄ ZvÃÅe a mÃt pÅÃstup k metodám zvÃÅete, aby králÃci mohli dÄlat to, co dÄlajà âobecnáâ zvÃÅata.
Syntaxe pro rozÅ¡ÃÅenà jiné tÅÃdy je: class DÃtÄ extends RodiÄ.
VytvoÅme tÅÃdu KrálÃk, která bude zdÄdÄna z tÅÃdy ZvÃÅe:
class KrálÃk extends ZvÃÅe {
schovejSe() {
alert(`${this.jméno} se schovává!`);
}
}
let králÃk = new KrálÃk("BÃlý králÃk");
králÃk.bÄž(5); // BÃlý králÃk bÄžà rychlostà 5.
králÃk.schovejSe(); // BÃlý králÃk se schovává!
Objekt tÅÃdy KrálÃk má pÅÃstup jak k metodám tÅÃdy KrálÃk, napÅ. králÃk.schovejSe(), tak k metodám tÅÃdy ZvÃÅe, napÅ. králÃk.bÄž().
KlÃÄové slovo extends vnitÅnÄ funguje na principu staré dobré mechaniky prototypů. Nastavà KrálÃk.prototype.[[Prototype]] na ZvÃÅe.prototype. Jestliže tedy metoda nenà nalezena v KrálÃk.prototype, JavaScript ji vezme ze ZvÃÅe.prototype.
NapÅÃklad aby motor nalezl metodu králÃk.bÄž, provÄÅà (na obrázku zdola nahoru):
- Objekt
králÃk(nemá žádnébÄž). - Jeho prototyp, tedy
KrálÃk.prototype(máschovejSe, ale nebÄž). - Jeho prototyp, což je (důsledkem
extends)ZvÃÅe.prototype, který koneÄnÄ má metodubÄž.
Jak si můžeme pamatovat z kapitoly Nativnà prototypy, samotný JavaScript použÃvá prototypovou dÄdiÄnost pro vestavÄné objekty. NapÅÃklad Date.prototype.[[Prototype]] je Object.prototype. Proto majà data pÅÃstup k obecným objektovým metodám.
extends smà být jakýkoli výrazSyntaxe tÅÃdy umožÅuje za extends specifikovat nejenom tÅÃdu, ale jakýkoli výraz.
NapÅÃklad volánà funkce, které generuje rodiÄovskou tÅÃdu:
function f(vÄta) {
return class {
ÅekniAhoj() { alert(vÄta); }
};
}
class Uživatel extends f("Ahoj") {}
new Uživatel().ÅekniAhoj(); // Ahoj
Zde je tÅÃda Uživatel zdÄdÄna z výsledku volánà f("Ahoj").
To může být užiteÄné pro pokroÄilé programovacà vzory, když použÃváme funkce ke generovánà tÅÃd závisejÃcÃch na mnoha podmÃnkách a můžeme z nich dÄdit.
PÅepisovánà metod
Nynà pojÄme dál a pÅepiÅ¡me metodu. StandardnÄ se vÅ¡echny metody, které nejsou uvedeny v class KrálÃk, berou z class ZvÃÅe rovnou beze zmÄn.
Jestliže vÅ¡ak specifikujeme ve tÅÃdÄ KrálÃk svou vlastnà metodu, napÅ. stůj(), bude mÃsto toho použita ona:
class KrálÃk extends ZvÃÅe {
stůj() {
// ...nynà bude pÅi volánà králÃk.stůj() použita tato metoda
// namÃsto stůj() ze tÅÃdy ZvÃÅe
}
}
Obvykle vÅ¡ak nechceme rodiÄovskou metodu úplnÄ nahradit, ale spÃÅ¡e na nà stavÄt, abychom jejà funkcionalitu vylepÅ¡ili nebo rozÅ¡ÃÅili. UdÄláme nÄco v našà metodÄ, ale v tomto procesu, pÅed nÃm nebo po nÄm voláme rodiÄovskou metodu.
K tomuto úÄelu tÅÃdy poskytujà klÃÄové slovo âsuperâ.
super.metoda(...)volá rodiÄovskou metodu.super(...)volá rodiÄovský konstruktor (pouze uvnitÅ naÅ¡eho konstruktoru).
NapÅÃklad nechme naÅ¡eho králÃka, aby se po zastavenà automaticky schoval:
class ZvÃÅe {
constructor(jméno) {
this.rychlost = 0;
this.jméno = jméno;
}
bÄž(rychlost) {
this.rychlost = rychlost;
alert(`${this.jméno} bÄžà rychlostà ${this.rychlost}.`);
}
stůj() {
this.rychlost = 0;
alert(`${this.jméno} klidnÄ stojÃ.`);
}
}
class KrálÃk extends ZvÃÅe {
schovejSe() {
alert(`${this.jméno} se schovává!`);
}
stůj() {
super.stůj(); // volá rodiÄovskou metodu stůj
this.schovejSe(); // a poté schovejSe
}
}
let králÃk = new KrálÃk("BÃlý králÃk");
králÃk.bÄž(5); // BÃlý králÃk bÄžà rychlostà 5.
králÃk.stůj(); // BÃlý králÃk klidnÄ stojÃ. BÃlý králÃk se schovává!
Nynà má KrálÃk metodu stůj, která pÅi provádÄnà volá rodiÄovskou metodu super.stůj().
superJak jsme zmÃnili v kapitole Å ipkové funkce podruhé, Å¡ipkové funkce nemajà super.
Pokud k nÄmu pÅistoupÃme, pÅevezme se z vnÄjšà funkce. NapÅÃklad:
class KrálÃk extends ZvÃÅe {
stůj() {
setTimeout(() => super.stůj(), 1000); // za 1 sekundu volá rodiÄovskou metodu stůj
}
}
super v Å¡ipkové funkci je stejné jako ve stůj(), funguje tedy tak, jak je zamýšleno. Kdybychom zde uvedli âobyÄejnouâ funkci, nastala by chyba:
// NeoÄekávaný super
setTimeout(function() { super.stůj() }, 1000);
PÅepisovánà konstruktorů
S konstruktory se to zaÄÃná trochu zamotávat.
Až dosud KrálÃk nemÄl svůj vlastnà constructor.
Jestliže tÅÃda rozÅ¡iÅuje jinou tÅÃdu a nemá constructor, podle specifikace se vygeneruje následujÃcà âprázdnýâ constructor:
class KrálÃk extends ZvÃÅe {
// generován pro rozÅ¡iÅujÃcà tÅÃdy bez vlastnÃho konstruktoru
constructor(...argumenty) {
super(...argumenty);
}
}
Jak vidÃme, v zásadÄ volá rodiÄovský constructor a pÅedá mu vÅ¡echny argumenty. To se stane, když si nenapÃÅ¡eme svůj vlastnà konstruktor.
Nynà pÅidejme do tÅÃdy KrálÃk vlastnà konstruktor, který bude navÃc k vlastnosti jméno specifikovat vlastnost délkaUcha:
class ZvÃÅe {
constructor(jméno) {
this.rychlost = 0;
this.jméno = jméno;
}
// ...
}
class KrálÃk extends ZvÃÅe {
constructor(jméno, délkaUcha) {
this.rychlost = 0;
this.jméno = jméno;
this.délkaUcha = délkaUcha;
}
// ...
}
// Nefunguje!
let králÃk = new KrálÃk("BÃlý králÃk", 10); // Chyba: this nenà definováno.
Ouha! Obdrželi jsme chybu. Nynà nemůžeme vytváÅet králÃky. Co bylo Å¡patnÄ?
StruÄná odpovÄÄ znÃ:
- Konstruktory ve zdÄdÄných tÅÃdách musejà volat
super(...)a (!) musejà to udÄlat pÅed použitÃmthis.
â¦Ale proÄ? Co se tady dÄje? Tento požadavek zajisté vypadá podivnÄ.
SamozÅejmÄ vysvÄtlenà existuje. PojÄme do detailů, abyste doopravdy pochopili, co se tady odehrává.
V JavaScriptu je rozdÃl mezi konstruktorem zdÄdÄné tÅÃdy (tzv. âodvozeným konstruktoremâ) a jinými funkcemi. Odvozený konstruktor má speciálnà internà vlastnost [[ConstructorKind]]:"derived". To je speciálnà vnitÅnà štÃtek.
Tato vlastnost ovlivÅuje jeho chovánà s new.
- Když je pomocÃ
newvolána obvyklá funkce, vytvoÅà prázdný objekt a pÅiÅadà jej dothis. - Ale když se spustà odvozený konstruktor, neudÄlá to. OÄekává, že tuto práci odvede rodiÄovský konstruktor.
Odvozený konstruktor tedy musà volat super, aby spustil svůj rodiÄovský (základnÃ, bázový) konstruktor, jinak objekt pro this nebude vytvoÅen a my dostaneme chybu.
Aby konstruktor KrálÃk fungoval, musà volat super() jeÅ¡tÄ pÅed použitÃm this, napÅÃklad:
class ZvÃÅe {
constructor(jméno) {
this.rychlost = 0;
this.jméno = jméno;
}
// ...
}
class KrálÃk extends ZvÃÅe {
constructor(jméno, délkaUcha) {
super(jméno);
this.délkaUcha = délkaUcha;
}
// ...
}
// nynà je to v poÅádku
let králÃk = new KrálÃk("BÃlý králÃk", 10);
alert(králÃk.jméno); // BÃlý králÃk
alert(králÃk.délkaUcha); // 10
PÅepisovánà tÅÃdnÃch polÃ: záludnost
Tato poznámka pÅedpokládá, že již máte s tÅÃdami urÄité zkuÅ¡enosti, možná i z jiných programovacÃch jazyků.
Poskytuje lepšà náhled do jazyka a rovnÄž vysvÄtluje chovánÃ, které může být zdrojem chyb (ale ne pÅÃliÅ¡ Äasto).
Pokud se vám bude zdát obtÞné jà porozumÄt, prostÄ ji pÅeskoÄte a pokraÄujte ve ÄtenÃ. Pak se k nà vraÅ¥te nÄkdy pozdÄji.
PÅepisovat můžeme nejen metody, ale i tÅÃdnà pole.
NicménÄ když pÅistoupÃme k pÅepsanému poli v rodiÄovském konstruktoru, nastane oÅ¡idné chovánÃ, ponÄkud odliÅ¡né od vÄtÅ¡iny ostatnÃch programovacÃch jazyků.
Uvažujme tento pÅÃklad:
class ZvÃÅe {
jm̩no = 'zv́e';
constructor() {
alert(this.jméno); // (*)
}
}
class KrálÃk extends ZvÃÅe {
jméno = 'králÃk';
}
new ZvÃÅe(); // zvÃÅe
new KrálÃk(); // zvÃÅe
Zde tÅÃda KrálÃk rozÅ¡iÅuje tÅÃdu ZvÃÅe a pÅepisuje pole jméno svou vlastnà hodnotou.
Ve tÅÃdÄ KrálÃk nenà vlastnà konstruktor, takže se zavolá konstruktor tÅÃdy ZvÃÅe.
ZajÃmavé je, že v obou pÅÃpadech new ZvÃÅe() i new KrálÃk() volánà alert na Åádku (*) zobrazà zvÃÅe.
Jinými slovy, rodiÄovský konstruktor vždy použÃvá svou vlastnà hodnotu pole, ne pÅepsanou.
Co je na tom zvláštnÃho?
Pokud to jeÅ¡tÄ nenà jasné, prosÃme porovnejte si to s metodami.
Zde je stejný kód, ale mÃsto pole this.jméno voláme metodu this.zobrazJméno():
class ZvÃÅe {
zobrazJméno() { // namÃsto this.jméno = 'zvÃÅe'
alert('zvÃÅe');
}
constructor() {
this.zobrazJméno(); // namÃsto alert(this.jméno);
}
}
class KrálÃk extends ZvÃÅe {
zobrazJméno() {
alert('králÃk');
}
}
new ZvÃÅe(); // zvÃÅe
new KrálÃk(); // králÃk
ProsÃme vÅ¡imnÄte si: nynà je výstup odliÅ¡ný.
A to je to, co pÅirozenÄ oÄekáváme. Když je v odvozené tÅÃdÄ volán rodiÄovský konstruktor, použije pÅepsanou metodu.
â¦Ale pro tÅÃdnà pole tomu tak nenÃ. Jak bylo uvedeno, rodiÄovský konstruktor vždy použÃvá rodiÄovské pole.
ProÄ je zde tento rozdÃl?
Důvod spoÄÃvá v poÅadà inicializace polÃ. TÅÃdnà pole je inicializováno:
- v bázové tÅÃdÄ (která žádnou tÅÃdu nerozÅ¡iÅuje) pÅed konstruktorem,
- v odvozené tÅÃdÄ ihned po
super().
V naÅ¡em pÅÃpadÄ je KrálÃk odvozená tÅÃda. Nenà v nà žádný constructor(). Jak bylo dÅÃve uvedeno, je to totéž, jako by tam byl prázdný konstruktor obsahujÃcà pouze super(...argumenty).
Takže new KrálÃk() volá super(), tÃm spustà rodiÄovský konstruktor, a (podle pravidla pro odvozené tÅÃdy) jsou teprve poté inicializována jeho tÅÃdnà pole. Ve chvÃli spuÅ¡tÄnà rodiÄovského konstruktoru jeÅ¡tÄ neexistujà žádná pole tÅÃdy KrálÃk, takže se použijà pole tÅÃdy ZvÃÅe.
Tento drobný rozdÃl mezi poli a metodami je specifický pro JavaScript.
NaÅ¡tÄstà se toto chovánà projevuje jen tehdy, když je pÅepsané pole použito v rodiÄovském konstruktoru. Pak může být obtÞné pochopit, co se dÄje, proto to tady vysvÄtlujeme.
Kdyby to byl problém, můžeme ho opravit použitÃm metod nebo getterů/setterů namÃsto polÃ.
Super: vnitÅnà mechanismy, [[HomeObject]]
Jestliže tento tutoriál Ätete poprvé, můžete tuto Äást pÅeskoÄit.
Pojednává o vnitÅnÃch mechanismech v pozadà dÄdiÄnosti a super.
ProniknÄme trochu hloubÄji pod povrch super. UvidÃme tam zajÃmavé vÄci.
Nejprve je tÅeba ÅÃci, že podle vÅ¡eho, Äemu jsme se dosud nauÄili, je nemožné, aby super vůbec fungovalo!
Ano, zajisté, zeptejme se sami sebe, jak by to mÄlo technicky fungovat? Když se spustà objektová metoda, dostane jako this aktuálnà objekt. Pokud pak zavoláme super.metoda(), motor musà zÃskat metodu metoda z prototypu aktuálnÃho objektu. Ale jak?
Tento úkol se může zdát jednoduchý, ale nenÃ. Motor zná aktuálnà objekt this, takže může zÃskat rodiÄovskou metodu metoda jako this.__proto__.metoda. NaneÅ¡tÄstà takové ânaivnÃâ ÅeÅ¡enà nebude fungovat.
Demonstrujme si problém. Pro zjednoduÅ¡enà bez tÅÃd, jen s použitÃm planých objektů.
Pokud nechcete znát detaily, můžete tuto Äást pÅeskoÄit a pokraÄovat k podkapitole [[HomeObject]]. NeuÅ¡kodà vám to. Pokud chcete porozumÄt vÄcem do hloubky, pokraÄujte ve ÄtenÃ.
V následujÃcÃm pÅÃkladu králÃk.__proto__ = zvÃÅe. Nynà to zkusme: v králÃk.žer() zavolejme zvÃÅe.žer() pomocà this.__proto__:
let zvÃÅe = {
jm̩no: "Zv́e",
žer() {
alert(`${this.jméno} žere.`);
}
};
let králÃk = {
__proto__: zvÃÅe,
jméno: "KrálÃk",
žer() {
// pÅedpokládáme, že takto funguje super.žer()
this.__proto__.žer.call(this); // (*)
}
};
králÃk.žer(); // KrálÃk žere.
Na Åádku (*) pÅevezmeme metodu žer z prototypu (zvÃÅe) a zavoláme ji v kontextu aktuálnÃho objektu. ProsÃme vÅ¡imnÄte si, že zde je důležité .call(this), protože pouhé this.__proto__.žer() by volalo rodiÄovskou metodu žer v kontextu prototypu, ne aktuálnÃho objektu.
A ve výše uvedeném kódu to skuteÄnÄ funguje tak, jak zamýšlÃme: máme správné alert.
Nynà pÅidáme do ÅetÄzce jeden dalšà objekt. UvidÃme, jak se to rozbije:
let zvÃÅe = {
jm̩no: "Zv́e",
žer() {
alert(`${this.jméno} žere.`);
}
};
let králÃk = {
__proto__: zvÃÅe,
žer() {
// ...poskakujeme po okolà králiÄÃm stylem a zavoláme metodu rodiÄe (zvÃÅe)
this.__proto__.žer.call(this); // (*)
}
};
let ušatý = {
__proto__: králÃk,
žer() {
// ...udÄláme nÄco s dlouhýma uÅ¡ima a zavoláme metodu rodiÄe (králÃk)
this.__proto__.žer.call(this); // (**)
}
};
uÅ¡atý.žer(); // Chyba: PÅekroÄena maximálnà velikost zásobnÃku
Kód už nefunguje! Když se pokusÃme zavolat uÅ¡atý.žer(), uvidÃme chybu.
Nemusà to být zcela zÅejmé, ale když si projdeme volánà uÅ¡atý.žer(), uvidÃme proÄ. Na obou ÅádcÃch (*) i (**) je hodnota this aktuálnà objekt (uÅ¡atý). To je podstatné: vÅ¡echny objektové metody dostanou jako this aktuálnà objekt, ne prototyp nebo nÄco jiného.
Na obou ÅádcÃch (*) a (**) je tedy hodnota this.__proto__ naprosto stejná: králÃk. Oba volajà králÃk.žer v nekoneÄné smyÄce, aniž by v ÅetÄzci postoupily výš.
Na obrázku je vidÄt, co se stane:
-
UvnitÅ
uÅ¡atý.žer()Åádek(**)volákrálÃk.žera poskytne muthis=uÅ¡atý.// uvnitÅ uÅ¡atý.žer() máme this = uÅ¡atý this.__proto__.žer.call(this) // (**) // se promÄnà na uÅ¡atý.__proto__.žer.call(this) // to je králÃk.žer.call(this); -
Pak na Åádku
(*)metodykrálÃk.žerbychom rádi pÅedali volánà v ÅetÄzci jeÅ¡tÄ výš, alethis=uÅ¡atý, takžethis.__proto__.žerje opÄtkrálÃk.žer!// uvnitÅ králÃk.žer() máme rovnÄž this = uÅ¡atý this.__proto__.žer.call(this) // (*) // se promÄnà na uÅ¡atý.__proto__.žer.call(this) // neboli (opÄt) králÃk.žer.call(this); -
â¦Takže
králÃk.žervolá sama sebe v nekoneÄné smyÄce, protože nemůže postoupit nikam výš.
Tento problém nelze vyÅeÅ¡it pouze pomocà this.
[[HomeObject]]
Aby JavaScript poskytl ÅeÅ¡enÃ, pÅidává navÃc jednu speciálnà internà vlastnost funkcÃ: [[HomeObject]].
Když je funkce specifikována jako metoda tÅÃdy nebo objektu, tento objekt se stane hodnotou jejà vlastnosti [[HomeObject]].
Pak jej super použÃvá k tomu, aby vyhodnotil rodiÄovský prototyp a jeho metody.
PodÃvejme se, jak to funguje, nejprve s planými objekty:
let zvÃÅe = {
jm̩no: "Zv́e",
žer() { // zvÃÅe.žer.[[HomeObject]] == zvÃÅe
alert(`${this.jméno} žere.`);
}
};
let králÃk = {
__proto__: zvÃÅe,
jméno: "KrálÃk",
žer() { // králÃk.žer.[[HomeObject]] == králÃk
super.žer();
}
};
let ušatý = {
__proto__: králÃk,
jméno: "Ušoun",
žer() { // ušatý.žer.[[HomeObject]] == ušatý
super.žer();
}
};
// funguje správnÄ
ušatý.žer(); // Ušoun žere.
DÃky mechanice [[HomeObject]] to funguje tak, jak jsme zamýšleli. Metoda, napÅ. uÅ¡atý.žer, zná svůj [[HomeObject]] a pÅevezme rodiÄovskou metodu z jeho prototypu. Bez jakéhokoli použità this.
Metody nejsou âvolnéâ
Jak již vÃme, funkce jsou v JavaScriptu obecnÄ âvolnéâ, nevázané k objektům. Mohou tedy být kopÃrovány mezi objekty a volány s jiným this.
Samotná existence [[HomeObject]] vÅ¡ak tento princip poruÅ¡uje, jelikož metody si pamatujà své objekty. [[HomeObject]] nemůže být zmÄnÄn, takže tato vazba je trvalá.
Jediné mÃsto v jazyce, kde je [[HomeObject]] použÃván, je super. Jestliže tedy metoda nepoužÃvá super, můžeme ji stále považovat za volnou a kopÃrovat ji mezi objekty. Ale se super se to může pokazit.
Následuje pÅÃklad Å¡patného výsledku super po kopÃrovánÃ:
let zvÃÅe = {
ÅekniAhoj() {
alert(`Jsem zvÃÅe`);
}
};
// králÃk je zdÄdÄn ze zvÃÅete
let králÃk = {
__proto__: zvÃÅe,
ÅekniAhoj() {
super.ÅekniAhoj();
}
};
let rostlina = {
ÅekniAhoj() {
alert("Jsem rostlina");
}
};
// strom je zdÄdÄn z rostliny
let strom = {
__proto__: rostlina,
ÅekniAhoj: králÃk.ÅekniAhoj // (*)
};
strom.ÅekniAhoj(); // Jsem zvÃÅe (?!?)
Volánà strom.ÅekniAhoj() zobrazà âJsem zvÃÅeâ. To je rozhodnÄ Å¡patnÄ.
Důvod je prostý:
- Na Åádku
(*)je metodastrom.ÅekniAhojzkopÃrována z objektukrálÃk. Možná jsme se chtÄli zdržet zdvojenà kódu? - JejÃ
[[HomeObject]]jekrálÃk, protože byla vytvoÅena v objektukrálÃk. Nenà žádný způsob, jak[[HomeObject]]zmÄnit. - UvnitÅ kódu metody
strom.ÅekniAhoj()je obsaženosuper.ÅekniAhoj(). Toto volánà postupuje nahoru od objektukrálÃka pÅebere tuto metodu z objektuzvÃÅe.
Na diagramu je vidÄt, co se stane:
Metody, ne funkÄnà vlastnosti
[[HomeObject]] je definován pro metody ve tÅÃdách i v planých objektech. Pro objekty vÅ¡ak metody musejà být specifikovány pÅÃmo jako metoda(), ne jako âmetoda: function()â.
RozdÃl pro nás nemusà být důležitý, ale pro JavaScript je podstatný.
Pro srovnánà v následujÃcÃm pÅÃkladu použijeme syntaxi bez metod. Vlastnost [[HomeObject]] se nenastavà a dÄdiÄnost nefunguje:
let zvÃÅe = {
žer: function() { // toto pÃÅ¡eme úmyslnÄ namÃsto žer() {...
// ...
}
};
let králÃk = {
__proto__: zvÃÅe,
žer: function() {
super.žer();
}
};
králÃk.žer(); // Chyba pÅi volánà super (protože nenà žádný [[HomeObject]])
ShrnutÃ
- Pro rozÅ¡ÃÅenà tÅÃdy:
class DÃtÄ extends RodiÄ:- To znamená, že
DÃtÄ.prototype.__proto__budeRodiÄ.prototype, takže metody budou zdÄdÄny.
- To znamená, že
- Když pÅepisujeme konstruktor:
- V konstruktoru tÅÃdy
DÃtÄmusÃme pÅed použitÃmthiszavolat rodiÄovský konstruktor pomocÃsuper().
- V konstruktoru tÅÃdy
- Když pÅepisujeme jinou metodu:
- V metodÄ tÅÃdy
DÃtÄmůžeme pomocÃsuper.metoda()volat metodu tÅÃdyRodiÄ.
- V metodÄ tÅÃdy
- VnitÅnà záležitosti:
- Metody si pamatujà svou tÅÃdu nebo objekt v internà vlastnosti
[[HomeObject]]. TÃmto způsobemsupervyhodnocuje rodiÄovské metody. - Nenà tedy bezpeÄné kopÃrovat metodu obsahujÃcÃ
superz jednoho objektu do jiného.
- Metody si pamatujà svou tÅÃdu nebo objekt v internà vlastnosti
NavÃc:
- Å ipkové funkce nemajà vlastnÃ
thisanisuper, takže průhlednÄ zapadajà do okolnÃho kontextu.
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â¦)