Veľa zmätku nastalo okolo JavaScriptu. Jeho neobyčajné vlastnosti veľa nás radšej ignoruje, akoby mali pariť uzlinami. Našli sme si miesto toho zázračné formulky, ktoré nám pomáhajú priepasť prekonávať. Navyše, množstvo zdrojov uvádza nekompletné, či dokonca nesprávne postupy. Špecifikácia nie je veľkým pomocníkom a k tomu všetkému sú tu rozdiely medzi implementáciami.

Všetci vieme:

  • JavaScript má prototypovú dedičnost.
  • Na dedenie je vlastnosť prototype.
  • Na inštancovanie objektu používame funkcie, ktoré sa podobajú ako na triedy, tak na konštruktory.

a strácame sa:

  • Čo je to prototypová dedičnost?
  • Akú úlohu hrá vlastnosť prototype v dedičnosti?
  • Ako funguje inštancovanie objektu z konštruktora?

Dedičnosť medzi objektami

Prototypová dedičnost, byť termín nesprávny, vhodný sťa metafora jest. (Používať budem i termíny ako napríklad „trieda“, ktoré nie sú tak celkom správne v kontexte JavaScriptu).

Na spodku zázrakov JavaScriptu je dedičnosť medzi objektami (nemýliť s triedami). Na to aby sme pochopili ako funguje dedenie tried, je dobré vedieť ako môže jeden objekt dediť od druhého. Príklad:

var fruit = { taste: "sweet" };
var apple = { color: "red" };

// Čil zázrak snaň sa!

alert( apple.taste ); // => "sweet"

Zázrak, ktorý sa musí stať je prepojenie objektov apple a fruit. Čiže ak sa spýtam na apple.taste, JavaScript musí vedieť, že ak taste nie je definovaná pre apple tak sa musí pozrieť na fruit.

Existuje vlastnosť každého objektu v JavaScripte, o ktorej nám súčasné implementácie viac-menej mlčia. Všetci sme už počuli o vlastnosti prototype, málo je však počut o __proto__. Je to preto, že __proto__ je v špecifikácii ECMAScript 262 označená ako interná (skrytá) a nemali by sme teda na ňu ako programátori šahať. (Špecifikácia hovorí o tejto vlastnosti ako o [[Prototype]]).

I napriek tomu dve JavaScriptové implementácie (SpiderMonkey od Mozilly a V8 od Google) ju sprístupňujú a pomenúvajú __proto__ (budem teda používať toto pomenovanie). Rád by som tu zdôraznil, že ide o neštandardnú internú vlastnosť, ale nám veľmi dobre poslúži na pochopenie toho čo sa v JavaScripte de­je.

Oný zázrak je teda v tom, že apple.__proto__ nastavíme na fruit:

var fruit = { taste: "sweet" };
var apple = { color: "red" };

apple.__proto__ = fruit;

alert( apple.taste ); // => "sweet"

→ Vyskúšajte

Objekt apple dedí od fruit, vďaka vlastnosti __proto__. Ak sa spýtame na hodnotu vlastnosti taste, JavaScript sa ju pokúsi nájsť na objekte apple. Ak ju objekt apple nemá, mrkne sa do objektu apple.__proto__, ak ani tam nič, tak apple.__proto__.__proto__atď. V našom prípade sa zastaví na apple.__proto__, pretože ukazuje na objekt fruit a ten vlastnosť taste má.

Ak chcem objektu apple zmeniť chuť na "sour", nič mi nebráni. Objekt fruit bude stále sladký:

apple.taste = "sour";
alert( apple.taste ); // => "sour"
alert( fruit.taste ); // => "sweet"

→ Vyskúšajte

V tomto momente apple dostáva vlastný taste a JavaScript už nemusí snoriť po __proto__ aby ju našiel.

Je dôležité si uvedomiť, že s __proto__ sa za normálnych okolností nestretneme. Budeme dokonca nútení ho nepoužívať, pretože nie je definovaný vo všetkých implementáciách. V tejto sérii slúži hlavne na vysvetlenie vnútorných pochodov v JavaScripte.

Ďalšia časť: