Prototypová dědičnost v JavaScriptu

Prototypová dědičnost v JavaScriptu

Prototypy jsou organizovaný způsob práce s objekty. Dědičnost je mechanismus, který umožňuje objektům převzít(zdědit) atributy a metody od jiných objektů.

Prototypová dědičnost je geniálně jednoduchý koncept, nicméně je matoucí pro začátečníky, kteří už dříve programovali v jazyce, který podporoval dědičnost tříd (Java, PHP nebo C#). Mnoho programátorů je zvyklá pracovat spíše s třídami, které javascript ještě donedávna nepodporoval.

Prototyp

Každý objekt v JavaScriptu má vlastnost prototype, která ukazuje na jiný objekt a slouží jako fallback objekt. Tomuto objektu se říká prototyp objektu a slouží jako základ dědičnost. Všechny objekty dědí ze speciální objektu, kterým je základní objekt.

Kroky pro vyhledání členských proměnných v objektu jsou velmi jednoduché:

  1. Hledá členskou proměnnou v objektu. Pokud je nalezen, vratí hodnotu této vlastnosti. Jinak krok 2.
  2. Hledá vlastnost v Prototype objektu. Pokud je nalezena, vratí hodnotu této vlastnosti.

Prototype chain

Představte si prototyp jako vazbu mezi dvěma objekty. Tím nám vzniknou objekty spojené s jinými objekty, které jsou takhle "zřetězeny“ pomocí prototypů. Není pak překvapivé, že se tomuhle říká prototypový řetězec (prototype chain)^gettyfy.

Když chceme, aby jeden objekt dědil od druhého, nastavíme jeho vlastnost prototype jako referenci na druhý objekt.

Když se na objekt zeptáme na hodnotu nějaké vlastnosti nebo metody, kterou nemá, prohledá se řetězec prototype objektů a hodnota se hledá v prototype objektech. Pokud se hodnota v prototype objektech nenajde, vrátí se undefined.

Příklad prototypové dědičnosti

Základní syntaxe pro vytvoření dědičnosti v JavaScriptu je následující:

function A() {}
function B() {}

// Nastavení prototype chain
B.prototype = Object.create(A.prototype);

// Nastavení konstruktoru pro B
B.prototype.constructor = B;

Jiný způsob jak dědit

const A = { a: 1 }
const B = { b: 2 }
const C = { c: 3 }

B.__proto__ = A;
C.__proto__ = B;

Výše uvedený kód vytvoří objekt B, který dědí od objektu A. Můžete pak vytvořit instance objektu B pomocí konstruktoru:

let b = new B();

Můžete také přidat vlastnosti a metody k objektu B pomocí prototype:

B.prototype.sayHi = function() {
  console.log("Hi!");
};

b.sayHi(); // Vytiskne "Hi!"

Dokonce můžeme vytvořit objekt, který nedědí nic. Takový objekt asi nebude moc praktický, ale jak víme, co není zákázáno je dovoleno :).

var objektPrazdny = Object.create(null)
typeof objektPrazdny.toString // 'undefined'