Vytvoření objektu stejným konstruktorem
Představme si, že máme libovolný objekt obj, který je vytvořen konstruktorem – nevíme jakým, ale rádi bychom pomocí něj vytvořili nový objekt.
Můžeme to udělat takto?
let obj2 = new obj.constructor();
Uveďte příklad konstruktoru pro obj, pro který by takový kód správně fungoval. A příklad, pro který by fungoval špatně.
Tento přístup můžeme použít, pokud jsme si jisti, že vlastnost "constructor" obsahuje správnou hodnotu.
Například pokud se nedotkneme standardní vlastnosti "prototype", pak bude tento kód zaručeně fungovat:
function Uživatel(jméno) {
this.jméno = jméno;
}
let uživatel = new Uživatel('Jan');
let uživatel2 = new uživatel.constructor('Petr');
alert( uživatel2.jméno ); // Petr (funguje!)
Funguje to, protože Uživatel.prototype.constructor == Uživatel.
…Ale pokud někdo dejme tomu přepíše Uživatel.prototype a zapomene znovu vytvořit constructor, aby odkazoval na Uživatel, pak to selže.
Například:
function Uživatel(jméno) {
this.jméno = jméno;
}
Uživatel.prototype = {}; // (*)
let uživatel = new Uživatel('Jan');
let uživatel2 = new uživatel.constructor('Petr');
alert( uživatel2.jméno ); // undefined
Proč je uživatel2.jméno undefined?
Takto funguje new uživatel.constructor('Petr'):
- Nejprve hledá
constructorv objektuuživatel. Nic. - Pak postupuje řetězcem prototypů. Prototyp objektu
uživateljeUživatel.prototypea ani ten nemá žádnýconstructor(protože jsme ho „zapomněli“ správně nastavit!). - Postupuje řetězcem dále nahoru.
Uživatel.prototypeje planý objekt a jeho prototypem je vestavěnýObject.prototype. - Nakonec pro vestavěný
Object.prototypeje vestavěnýObject.prototype.constructor == Object. Ten se tedy použije.
Nakonec tedy máme let uživatel2 = new Object('Petr').
To pravděpodobně není to, co chceme. Rádi bychom vytvořili new Uživatel, ne new Object. To je důsledek chybějící vlastnosti constructor.
(Jen pro případ, že vás to zajímá: volání new Object(...) konvertuje svůj argument na objekt. To je teoretická záležitost, v praxi nikdo nevolá new Object s hodnotou a obecně vůbec nepoužíváme new Object k vytváření objektů.)