Inheritance
Inheritance is het proces waarbij een object op een ander object kan worden gebaseerd. Hierdoor kunnen de objecten elkaars eigenschappen delen.
Ik heb het Hero
prototype gemaakt en gebruikt om een nieuw object te maken met de naam superman
. Maar we doen niets met dit object. Dus laten we daar voor zorgen door een andere functie te maken met de naam dialogue
.
function dialogue() {
console.log('I am ' + this.name);
}
Maar als we onze code nu uitvoeren, zal er niets gebeuren omdat deze functie niet weet wat de naam werkelijk is. Daarvoor moeten we
Ik wil dat deze nieuwe functie dezelfde eigenschappen heeft als die van de Hero
. In plaats van ze in deze functie op te schrijven, kunnen we JavaScript eenvoudigweg vertellen ze te erven van het Hero
-prototype.
Dit is mogelijk met behulp van de prototype
-eigenschap die in elk object in JavaScript beschikbaar is.
Door dialogue
op Hero.prototype
te plaatsen, hebben we het beschikbaar gemaakt voor alle instanties van Hero
.
Differentiële overerving
JavaScript komt ook met een ander overervingsmodel dat “differentiële overerving” wordt genoemd. In dit model worden de methodes niet gekopieerd van de ouder naar het kind. Maar in plaats daarvan is er een link tussen de kinderen en hun ouder object.
Hier, superman
heeft eigenlijk geen eigen methode genaamd dialogue()
. Maar hoe werkt superman.dialogue()
dan?
Wanneer de JavaScript-engine superman.dialogue()
in de code tegenkomt, zoekt het naar de eigenschap dialogue
in het object superman
. Als die niet wordt gevonden, zoekt hij in de prototype-keten naar superman
’s bovenliggende Hero.prototype
. Daar zal het Hero.prototype.dialogue
vinden en het aanroepen met een this
die is gebonden aan superman
.
Object.create()
We kunnen dit nog exclusiever maken door een nieuwe klasse voor Superman
te maken die de eigenschappen van het Hero
prototype zal overerven. We kunnen dit doen door het prototype van Superman
toe te wijzen aan het Hero
prototype zoals dit:
function Superman() {}
Superman.prototype = Hero.prototype
Maar wat dit doet is dat het gewoon zowel Superman
als Hero
gelijk maakt. Wat we echt nodig hebben is een nieuw object dat is gebaseerd op het Hero
prototype. Sinds ES5, heeft JavaScript een ingebouwde functie genaamd Object.create()
. Laten we die hier gebruiken zoals hieronder getoond:
Superman.prototype = Object.create(Hero.prototype);
Dit zal een nieuw leeg object maken dat is gebaseerd op het Hero
prototype en het toewijzen aan het Superman
prototype. Dus alle eigenschappen die we hebben in het Hero
prototype kunnen nu worden benaderd door het Superman
prototype. Dus in plaats van new Hero
aan te roepen, kunnen we new Superman
aanroepen en alles zal nog steeds werken zoals het hoort.
Maar als u de uitvoer van dichterbij bekijkt, zult u merken dat er een undefined
in staat. Dat komt omdat de Hero
op dit moment alleen een constructor voor zichzelf is. We moeten call
de eigenschappen van Hero
binnen het Superman
prototype.
function Superman() {
Hero.call(this, 'Superman', 'Clark Kent', 'Krypton')
}
Laten we een andere constructor maken genaamd MarvelMovies
zoals hieronder getoond:
function MarvelMovies(movieName, releaseYear) {
this.movieName = movieName;
this.releaseYear = releaseYear;
}
Wanneer een functie wordt gebruikt als een constructor, verwijst this
naar het nieuwe object dat we maken. Dus in deze constructor heb ik movieName
en releaseYear
als argumenten genomen en die waarden toegewezen aan de movieName
en releaseYear
eigenschappen van onze nieuwe MarvelMovies
instantie met de naam avengers
.
var avengers = new MarvelMovies("avengers", 2012);
Ik ga dan een nieuwe methode output
voor dit prototype maken, zoals hieronder te zien is:
MarvelMovies.prototype.output = function() {
return "Movie: " + this.movieName + " Released in " + this.releaseYear;
}
console.log(avengers.output());
Toekomstige overerving
Een echt geweldig aspect van overerving is dat JavaScript je in staat stelt om de eigenschappen van een klasse te wijzigen of uit te breiden, zelfs nadat je hem hebt gedefinieerd.
JavaScript zal het prototype opzoeken wanneer het probeert om eigenschappen van een object te benaderen. U kunt dus klassen runtime wijzigen!
Om dit te illustreren, laten we een array maken zoals hieronder getoond:
var numbers = ;
Array.prototype.shuffle = function() {
return this.sort(function() {
return Math.round( Math.random() * 2) - 1;
});
};
console.log(numbers.shuffle());
Hier bestond de numbers
array al voordat de Array.prototype.shuffle
bestond. Maar in JavaScript gaat het opzoeken van eigenschappen omhoog in de prototype-keten. Daarom krijgt de array nog steeds toegang tot de nieuwe methode shuffle
, omdat hij al bestaat op de Array.prototype
wanneer we hem eigenlijk proberen te gebruiken.
In eenvoudige bewoordingen: we hebben een array gemaakt, zijn toen teruggegaan en hebben alle arrays toegang gegeven tot een nieuwe methode.