Pamatujte, že nové objekty lze vytvořit pomocí funkce konstruktoru, jako je new F()
.
Pokud F.prototype
je objekt, pak new
operátor jej používá k nastavení [[Prototype]]
pro nový objekt.
JavaScript měl prototypovou dědičnost od začátku. Byl to jeden ze základních rysů jazyka.
Ale za starých časů k němu nebyl přímý přístup. Jediná věc, která fungovala spolehlivě, byla "prototype"
vlastnost funkce konstruktoru, popsané v této kapitole. Existuje tedy mnoho skriptů, které jej stále používají.
Vezměte prosím na vědomí, že F.prototype
zde znamená běžnou vlastnost s názvem "prototype"
na F
. Zní to něco podobného jako výraz „prototyp“, ale zde máme skutečně na mysli běžnou vlastnost s tímto názvem.
Zde je příklad:
let animal = {
eats: true
};
function Rabbit(name) {
this.name = name;
}
Rabbit.prototype = animal;
let rabbit = new Rabbit("White Rabbit"); // rabbit.__proto__ == animal
alert( rabbit.eats ); // true
Nastavení Rabbit.prototype = animal
doslova uvádí následující:"Když new Rabbit
je vytvořen, přiřaďte mu [[Prototype]]
na animal
".
To je výsledný obrázek:
Na obrázku "prototype"
je vodorovná šipka, což znamená běžnou vlastnost, a [[Prototype]]
je vertikální, což znamená dědičnost rabbit
od animal
.
F.prototype
používá se pouze na new F
čas
F.prototype
vlastnost se používá pouze při new F
zavolá, přiřadí [[Prototype]]
nového objektu.
Pokud po vytvoření F.prototype
změny vlastností (F.prototype = <another object>
), pak nové objekty vytvořené new F
bude mít jiný objekt jako [[Prototype]]
, ale již existující objekty si ponechají ten starý.
Výchozí F.prototype, vlastnost konstruktoru
Každá funkce má "prototype"
majetek, i když jej nedodáme.
Výchozí "prototype"
je objekt s jedinou vlastností constructor
což ukazuje zpět na samotnou funkci.
Takhle:
function Rabbit() {}
/* default prototype
Rabbit.prototype = { constructor: Rabbit };
*/
Můžeme to zkontrolovat:
function Rabbit() {}
// by default:
// Rabbit.prototype = { constructor: Rabbit }
alert( Rabbit.prototype.constructor == Rabbit ); // true
Přirozeně, pokud nic neuděláme, constructor
vlastnost je dostupná všem králíkům prostřednictvím [[Prototype]]
:
function Rabbit() {}
// by default:
// Rabbit.prototype = { constructor: Rabbit }
let rabbit = new Rabbit(); // inherits from {constructor: Rabbit}
alert(rabbit.constructor == Rabbit); // true (from prototype)
Můžeme použít constructor
vlastnost k vytvoření nového objektu pomocí stejného konstruktoru jako stávající.
Jako zde:
function Rabbit(name) {
this.name = name;
alert(name);
}
let rabbit = new Rabbit("White Rabbit");
let rabbit2 = new rabbit.constructor("Black Rabbit");
To se hodí, když máme objekt a nevíme, který konstruktor byl pro něj použit (např. pochází z knihovny třetí strany) a potřebujeme vytvořit další stejného druhu.
Ale asi nejdůležitější věc o "constructor"
je to…
…Samotný JavaScript nezajišťuje správné "constructor"
hodnotu.
Ano, existuje ve výchozím nastavení "prototype"
pro funkce, ale to je vše. Co se s tím stane později – je zcela na nás.
Zejména pokud nahradíme výchozí prototyp jako celek, nebude zde žádné "constructor"
v něm.
Například:
function Rabbit() {}
Rabbit.prototype = {
jumps: true
};
let rabbit = new Rabbit();
alert(rabbit.constructor === Rabbit); // false
Abychom dodrželi správný "constructor"
můžeme se rozhodnout přidat/odebrat vlastnosti do výchozího "prototype"
místo přepsání jako celku:
function Rabbit() {}
// Not overwrite Rabbit.prototype totally
// just add to it
Rabbit.prototype.jumps = true
// the default Rabbit.prototype.constructor is preserved
Nebo případně znovu vytvořte constructor
vlastnost ručně:
Rabbit.prototype = {
jumps: true,
constructor: Rabbit
};
// now constructor is also correct, because we added it
Shrnutí
V této kapitole jsme stručně popsali způsob nastavení [[Prototype]]
pro objekty vytvořené pomocí funkce konstruktoru. Později uvidíme pokročilejší programovací vzory, které na tom spoléhají.
Všechno je docela jednoduché, jen pár poznámek, aby bylo jasno:
F.prototype
vlastnost (nezaměňujte ji za[[Prototype]]
) nastaví[[Prototype]]
nových objektů přinew F()
se nazývá.- Hodnota
F.prototype
by měl být buď objekt nebonull
:jiné hodnoty nebudou fungovat. "prototype"
vlastnost má takový zvláštní účinek pouze tehdy, když je nastavena na funkci konstruktoru a je vyvolána pomocínew
.
U běžných objektů prototype
není nic zvláštního:
let user = {
name: "John",
prototype: "Bla-bla" // no magic at all
};
Ve výchozím nastavení mají všechny funkce F.prototype = { constructor: F }
, takže konstruktor objektu můžeme získat přístupem k jeho "constructor"
vlastnost.