Poznání prototypové dědičnosti v jazyce JavaScript

Dědičnost

Dědičnost je proces, při kterém může být jeden objekt založen na jiném. Díky tomu mohou objekty vzájemně sdílet své vlastnosti.

Vytvořil jsem prototyp Hero a použil ho k vytvoření nového objektu s názvem superman. S tímto objektem však nic neděláme. Postaráme se tedy o to vytvořením další funkce s názvem dialogue.

function dialogue() {
console.log('I am ' + this.name);
}

Pokud však nyní spustíme náš kód, nic se nestane, protože tato funkce neví, jaké je skutečné jméno. K tomu potřebujeme

Chci, aby tato nová funkce měla stejné vlastnosti jako funkce Hero. Místo toho, abychom je zapisovali uvnitř této funkce, můžeme jednoduše říci JavaScriptu, aby je zdědil od prototypu Hero.

To je možné pomocí vlastnosti prototype, která je v JavaScriptu k dispozici v rámci libovolného objektu.

Díky umístění dialogue na Hero.prototype jsme ji zpřístupnili všem instancím Hero.

Diferenciální dědičnost

JavaScript také přichází s dalším modelem dědičnosti, který se nazývá „diferenciální dědičnost“. V tomto modelu se metody nekopírují z rodiče na potomka. Ale místo toho existuje vazba mezi potomky a jejich rodičovským objektem.

Tady superman vlastně nemá svou vlastní metodu s názvem dialogue(). Jak ale potom funguje superman.dialogue()?“

Když JavaScriptový engine narazí v kódu na superman.dialogue(), hledá uvnitř objektu superman vlastnost s názvem dialogue. Když ji nenajde, vyhledá v řetězci prototypů nadřazený objekt superman Hero.prototype. Tam najde Hero.prototype.dialogue a zavolá ji pomocí this, který je svázán s superman.

Objekt.create()

Tento postup můžeme ještě více vylučovat tím, že vytvoříme novou třídu Superman, která bude dědit vlastnosti prototypu Hero. Můžeme to udělat tak, že prototypu Superman přiřadíme prototyp Hero takto:

function Superman() {}
Superman.prototype = Hero.prototype

Ale to dělá to, že to prostě zrovnoprávní jak Superman, tak Hero. Ve skutečnosti potřebujeme nový objekt, který je založen na prototypu Hero. Od verze ES5 obsahuje JavaScript vestavěnou funkci s názvem Object.create(). Použijme ji zde, jak je uvedeno níže:

Superman.prototype = Object.create(Hero.prototype);

Tím se vytvoří nový prázdný objekt, který je založen na prototypu Hero, a přiřadí se prototypu Superman. Takže všechny vlastnosti, které máme v prototypu Hero, jsou nyní přístupné prototypu Superman. Takže místo volání new Hero můžeme volat new Superman a vše bude stále fungovat, jak má.

Pokud se však na výstup podíváte pozorněji, všimnete si, že uvnitř je undefined. To proto, že v současné době je Hero konstruktor pouze sám pro sebe. Musíme call vlastnosti Hero uvnitř prototypu Superman.

function Superman() {
Hero.call(this, 'Superman', 'Clark Kent', 'Krypton')
}

Vytvoříme další konstruktor s názvem MarvelMovies, jak je uvedeno níže:

function MarvelMovies(movieName, releaseYear) {
this.movieName = movieName;
this.releaseYear = releaseYear;
}

Pokud je funkce použita jako konstruktor, this odkazuje na nový objekt, který vytváříme. V tomto konstruktoru jsem tedy vzal jako argumenty movieName a releaseYear a přiřadil tyto hodnoty vlastnostem movieName a releaseYear naší nové instance MarvelMovies s názvem avengers.

var avengers = new MarvelMovies("avengers", 2012);

Pro tento prototyp pak vytvořím novou metodu s názvem output, jak je uvedeno níže:

MarvelMovies.prototype.output = function() {
return "Movie: " + this.movieName + " Released in " + this.releaseYear;
}
console.log(avengers.output());

Příští dědičnost

Vskutku skvělým aspektem dědičnosti je to, že JavaScript umožňuje upravovat nebo rozšiřovat vlastnosti třídy i poté, co jste ji definovali.

JavaScript při pokusu o přístup k vlastnostem objektu vyhledá prototyp. Třídy tedy můžete za běhu měnit!

Pro ilustraci vytvoříme pole podle následujícího obrázku:

var numbers = ;
Array.prototype.shuffle = function() {
return this.sort(function() {
return Math.round( Math.random() * 2) - 1;
});
};
console.log(numbers.shuffle());

Tady pole numbers existovalo dříve než Array.prototype.shuffle. V JavaScriptu však vyhledávání vlastností probíhá až v řetězci prototypů. Proto pole stále získává přístup k nové metodě shuffle, protože existuje na Array.prototype, když se ji skutečně snažíme použít.

Zjednodušeně řečeno, vytvořili jsme pole, pak jsme se vrátili zpět a dali všem polím přístup k nové metodě.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.