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ť
prototypev 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 deje.
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"

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"

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ť:
- JavaScript zvnútra 1/4: Dedičnosť objektov
- JavaScript zvnútra 2/4: Konštruktory
- JavaScript zvnútra 3/4: Prototyp konštruktora
- JavaScript zvnútra 4/4: Dedičnosť medzi triedami