TÅÃda rozÅ¡iÅuje Object?
Jak vÃme, vÅ¡echny objekty bÄžnÄ dÄdà z Object.prototype a zÃskávajà pÅÃstup k âobecnýmâ objektovým metodám jako hasOwnProperty a podobnÄ.
NapÅÃklad:
class KrálÃk {
constructor(jméno) {
this.jméno = jméno;
}
}
let králÃk = new KrálÃk("Bobek");
// metoda hasOwnProperty je z Object.prototype
alert( králÃk.hasOwnProperty('jméno') ); // true
Pokud vÅ¡ak výslovnÄ uvedeme âclass KrálÃk extends Objectâ, bude se výsledek liÅ¡it od prostého âclass KrálÃkâ?
Jaký je rozdÃl?
Zde je pÅÃklad takového kódu (nefunguje â proÄ? opravte ho):
class KrálÃk extends Object {
constructor(jméno) {
this.jméno = jméno;
}
}
let králÃk = new KrálÃk("Bobek");
alert( králÃk.hasOwnProperty('jméno') ); // Chyba
Nejprve se podÃvejme, proÄ poslednà uvedený kód nefunguje.
Důvod bude zÅejmý, když se ho pokusÃme spustit. Konstruktor zdÄdÄné tÅÃdy musà volat super(), jinak nebude âdefinovánoâ âthisâ.
Zde je tedy oprava:
class KrálÃk extends Object {
constructor(jméno) {
super(); // pÅi dÄdÄnà je nutné volat rodiÄovský konstruktor
this.jméno = jméno;
}
}
let králÃk = new KrálÃk("Bobek");
alert( králÃk.hasOwnProperty('jméno') ); // true
To vÅ¡ak jeÅ¡tÄ nenà vÅ¡echno.
I po této opravÄ bude stále existovat důležitý rozdÃl mezi âclass KrálÃk extends Objectâ a class KrálÃk.
Jak vÃme, syntaxe âextendsâ nastavuje dva prototypy:
- Mezi
"prototype"konstruktorů (pro metody). - Mezi samotnými konstruktory (pro statické metody).
V pÅÃpadÄ class KrálÃk extends Object to znamená:
class KrálÃk extends Object {}
alert( KrálÃk.prototype.__proto__ === Object.prototype ); // (1) true
alert( KrálÃk.__proto__ === Object ); // (2) true
KrálÃk tedy nynà poskytuje pÅÃstup ke statickým metodám tÅÃdy Object pÅes tÅÃdu KrálÃk, napÅÃklad:
class KrálÃk extends Object {}
// bÄžnÄ voláme Object.getOwnPropertyNames
alert ( KrálÃk.getOwnPropertyNames({a: 1, b: 2})); // a,b
Jestliže vÅ¡ak nemáme extends Object, pak se KrálÃk.__proto__ nenastavà na Object.
Zde je ukázka:
class KrálÃk {}
alert( KrálÃk.prototype.__proto__ === Object.prototype ); // (1) true
alert( KrálÃk.__proto__ === Object ); // (2) false (!)
alert( KrálÃk.__proto__ === Function.prototype ); // jako standardnÄ kterákoli funkce
// chyba, ve tÅÃdÄ KrálÃk taková funkce nenÃ
alert ( KrálÃk.getOwnPropertyNames({a: 1, b: 2})); // Chyba
KrálÃk tedy v tomto pÅÃpadÄ neposkytuje pÅÃstup ke statickým metodám tÅÃdy Object.
Mimochodem, Function.prototype obsahuje âobecnéâ funkÄnà metody, napÅ. call, bind atd. Ty jsou definitivnÄ dostupné v obou pÅÃpadech, protože pro zabudovaný konstruktor tÅÃdy Object platà Object.__proto__ === Function.prototype.
Zde je obrázek:
Abychom to tedy zkrátili, existujà dva rozdÃly:
| class KrálÃk | class KrálÃk extends Object |
|---|---|
| â | musà v konstruktoru volat super() |
KrálÃk.__proto__ === Function.prototype |
KrálÃk.__proto__ === Object |