Öröklődés
Az öröklődés az a folyamat, amelynek segítségével egy objektum egy másikra épülhet. Ez lehetővé teszi, hogy az objektumok megosszák egymás tulajdonságait.
Elkészítettem a Hero
prototípust, és létrehoztam vele egy új superman
nevű objektumot. De ezzel az objektummal nem csinálunk semmit. Ezért gondoskodjunk erről úgy, hogy létrehozunk egy másik függvényt dialogue
néven.
function dialogue() {
console.log('I am ' + this.name);
}
De ha most futtatjuk a kódunkat, semmi sem fog történni, mert ez a függvény nem tudja, hogy valójában mi a név. Ehhez arra van szükségünk, hogy
Az új függvénynek ugyanazokkal a tulajdonságokkal kell rendelkeznie, mint a Hero
-nek. Ahelyett, hogy leírnánk őket ebben a függvényben, egyszerűen megmondhatjuk a JavaScriptnek, hogy örökítse őket a Hero
prototípusából.
Ez a prototype
tulajdonság segítségével lehetséges, amely bármely objektumon belül elérhető a JavaScriptben.
Azzal, hogy a dialogue
-t a Hero.prototype
-re helyeztük, elérhetővé tettük a Hero
minden példánya számára.
Differenciális öröklés
A JavaScript egy másik öröklési modellel is rendelkezik, amelyet “differenciális öröklésnek” nevezünk. Ebben a modellben a metódusok nem másolódnak át a szülőből a gyermekbe. De ehelyett van egy kapcsolat a gyerekek és a szülő objektum között.
Itt a superman
-nek valójában nincs saját dialogue()
nevű metódusa. De akkor hogyan működik a superman.dialogue()
?
Amikor a JavaScript motor a kódban találkozik a superman.dialogue()
metódussal, a superman
objektumon belül a dialogue
nevű tulajdonságot keresi. Ha nem talál ilyet, akkor a prototípusláncban a superman
Hero.prototype
szülőjéhez, Hero.prototype
-hez keres felfelé. Ott megtalálja a Hero.prototype.dialogue
-t, és meghívja azt egy this
-tel, amely a superman
-hez van kötve.
Object.create()
Ezt még exkluzívabbá tehetjük azzal, hogy létrehozunk egy új osztályt a Superman
számára, amely örökli a Hero
prototípus tulajdonságait. Ezt úgy tehetjük meg, hogy a Superman
prototípusát hozzárendeljük a Hero
prototípusához, így:
function Superman() {}
Superman.prototype = Hero.prototype
De ez csak annyit tesz, hogy a Superman
és a Hero
osztályokat egyenlővé teszi. Amire valójában szükségünk van, az egy új objektum, amely a Hero
prototípuson alapul. Az ES5 óta a JavaScript rendelkezik egy beépített függvénnyel, amelynek neve Object.create()
. Használjuk itt az alábbiak szerint:
Superman.prototype = Object.create(Hero.prototype);
Ez létrehoz egy új üres objektumot, amely a Hero
prototípuson alapul, és hozzárendeli a Superman
prototípushoz. Így a Hero
prototípusban lévő összes tulajdonságunkat elérhetjük a Superman
prototípusban. Tehát ahelyett, hogy a new Hero
-t hívnánk, hívhatjuk a new Superman
-t, és minden úgy fog működni, ahogyan kell.
De ha jobban megnézzük a kimenetet, észrevehetjük, hogy van benne egy undefined
. Ez azért van, mert jelenleg a Hero
csak önmagának konstruktora. A Hero
tulajdonságait a Superman
prototípuson belül kell call
megadni.
function Superman() {
Hero.call(this, 'Superman', 'Clark Kent', 'Krypton')
}
Hozzunk létre egy másik konstruktort MarvelMovies
néven az alábbiak szerint:
function MarvelMovies(movieName, releaseYear) {
this.movieName = movieName;
this.releaseYear = releaseYear;
}
Amikor egy függvényt konstruktorként használunk, a this
az általunk létrehozott új objektumra utal. Ebben a konstruktorban tehát movieName
és releaseYear
argumentumokat vettem, és ezeket az értékeket a avengers
nevű új MarvelMovies
példányunk movieName
és releaseYear
tulajdonságaihoz rendeltem.
var avengers = new MarvelMovies("avengers", 2012);
Ezután létrehozok egy új, output
nevű metódust ehhez a prototípushoz az alábbiakban látható módon:
MarvelMovies.prototype.output = function() {
return "Movie: " + this.movieName + " Released in " + this.releaseYear;
}
console.log(avengers.output());
Jövőbeni öröklés
Az öröklés igazán nagyszerű aspektusa, hogy a JavaScript lehetővé teszi, hogy egy osztály tulajdonságait még azután is módosítsuk vagy bővítsük, hogy már definiáltuk.
A JavaScript megnézi a prototípust, amikor megpróbáljuk elérni egy objektum tulajdonságait. Tehát futás közben is módosíthatjuk az osztályokat!
Az alábbiakban látható módon hozzunk létre egy tömböt ennek szemléltetésére:
var numbers = ;
Array.prototype.shuffle = function() {
return this.sort(function() {
return Math.round( Math.random() * 2) - 1;
});
};
console.log(numbers.shuffle());
Itt a numbers
tömb már a Array.prototype.shuffle
előtt is létezett. De a JavaScriptben a tulajdonságok keresése felfelé halad a prototípus-láncban. Ezért a tömb még mindig hozzáférést kap az új shuffle
metódushoz, mivel a Array.prototype
-nél létezik, amikor ténylegesen megpróbáljuk használni.
Egyszerűen fogalmazva, létrehoztunk egy tömböt, majd visszamentünk és minden tömbnek hozzáférést adtunk egy új metódushoz.