Arvelighed
Arvelighed er den proces, hvormed et objekt kan baseres på et andet. Dette gør det muligt for objekterne at dele hinandens egenskaber.
Jeg har oprettet prototypen Hero
og brugt den til at oprette et nyt objekt ved navn superman
. Men vi gør ikke noget med dette objekt. Så lad os tage os af det ved at oprette en anden funktion kaldet dialogue
.
function dialogue() {
console.log('I am ' + this.name);
}
Men hvis vi kører vores kode nu, vil der ikke ske noget, fordi denne funktion ikke ved, hvad navnet egentlig er. Derfor er vi nødt til at
Jeg ønsker, at denne nye funktion skal have de samme egenskaber som Hero
. I stedet for at skrive dem ned inde i denne funktion kan vi blot bede JavaScript om at arve dem fra Hero
-prototypen.
Dette er muligt ved hjælp af prototype
-egenskaben, der er tilgængelig inden for ethvert objekt i JavaScript.
Ved at placere dialogue
på Hero.prototype
har vi gjort den tilgængelig for alle forekomster af Hero
.
Differentiel arv
JavaScript har også en anden arvestandard, der kaldes “differentiel arv”. I denne model kopieres metoderne ikke fra forældrene til barnet. Men i stedet er der en forbindelse mellem børnene og deres forældreobjekt.
Her har superman
faktisk ikke sin egen metode, der hedder dialogue()
. Men hvordan fungerer superman.dialogue()
så?
Når JavaScript-motoren støder på superman.dialogue()
i koden, leder den efter egenskaben kaldet dialogue
inde i superman
-objektet. Når den ikke finder en sådan, kigger den opad i prototypekæden til superman
s overordnede Hero.prototype
. Der finder den Hero.prototype.dialogue
og kalder den med en this
, der er bundet til superman
.
Object.create()
Vi kan gøre dette endnu mere eksklusivt ved at oprette en ny klasse til Superman
, som arver egenskaberne fra Hero
-prototypen. Det kan vi gøre ved at tildele prototypen for Superman
til Hero
-prototypen på denne måde:
function Superman() {}
Superman.prototype = Hero.prototype
Men det, dette gør, er, at det blot gør både og Hero
ligeværdige. Det, vi i virkeligheden har brug for, er et nyt objekt, der er baseret på prototypen Hero
. Siden ES5 har JavaScript fået en indbygget funktion kaldet Object.create()
. Lad os bruge den her som vist nedenfor:
Superman.prototype = Object.create(Hero.prototype);
Dette vil oprette et nyt tomt objekt, der er baseret på Hero
-prototypen, og tildele det til Superman
-prototypen. Så alle de egenskaber, som vi har i Hero
-prototypen, kan nu tilgås af Superman
-prototypen. Så i stedet for at kalde new Hero
kan vi kalde new Superman
, og alt vil stadig fungere, som det skal.
Men hvis du kigger nærmere på output, vil du bemærke, at der er en undefined
inde i det. Det skyldes, at Hero
i øjeblikket kun er en konstruktor for sig selv. Vi skal call
egenskaberne for Hero
inde i Superman
prototypen.
function Superman() {
Hero.call(this, 'Superman', 'Clark Kent', 'Krypton')
}
Lad os oprette en anden konstruktor kaldet MarvelMovies
som vist nedenfor:
function MarvelMovies(movieName, releaseYear) {
this.movieName = movieName;
this.releaseYear = releaseYear;
}
Når en funktion bruges som konstruktor, refererer this
til det nye objekt, som vi opretter. Så i denne konstruktør har jeg taget movieName
og releaseYear
som argumenter og tildelt disse værdier til movieName
og releaseYear
-egenskaberne for vores nye MarvelMovies
-instans ved navn avengers
.
var avengers = new MarvelMovies("avengers", 2012);
Jeg opretter derefter en ny metode kaldet output
for denne prototype som vist nedenfor:
MarvelMovies.prototype.output = function() {
return "Movie: " + this.movieName + " Released in " + this.releaseYear;
}
console.log(avengers.output());
Future Inheritance
Et rigtig godt aspekt af arv er, at JavaScript giver dig mulighed for at ændre eller udvide en klasses egenskaber, selv efter at du har defineret den.
JavaScript slår op i prototypen, når du forsøger at få adgang til egenskaber på et objekt. Du kan altså ændre klasser på køretid!
For at illustrere dette kan vi oprette et array som vist nedenfor:
var numbers = ;
Array.prototype.shuffle = function() {
return this.sort(function() {
return Math.round( Math.random() * 2) - 1;
});
};
console.log(numbers.shuffle());
Her eksisterede arrayet numbers
før arrayet Array.prototype.shuffle
. Men i JavaScript går egenskabsopslagene opad i prototypekæden. Derfor får arrayet stadig adgang til den nye metode shuffle
, da det eksisterer på Array.prototype
, når vi rent faktisk forsøger at bruge det.
Simpelt sagt oprettede vi et array, og gik derefter tilbage og gav alle Arrays adgang til en ny metode.