Javaskriptin prototyyppiperinnöllisyyden ymmärtäminen

Perinnöllisyys

Perinnöllisyys on prosessi, jonka avulla yksi objekti voi perustua toiseen. Näin objektit voivat jakaa toistensa ominaisuuksia.

Olen luonut Hero-prototyypin ja käyttänyt sitä uuden superman-nimisen objektin luomiseen. Mutta emme tee tälle objektille mitään. Hoidetaan siis asia luomalla toinen funktio nimeltä dialogue.

function dialogue() {
console.log('I am ' + this.name);
}

Mutta jos suoritamme koodimme nyt, mitään ei tapahdu, koska tämä funktio ei tiedä, mikä nimi oikeasti on. Sitä varten meidän on

Tahdon, että tällä uudella funktiolla on samat ominaisuudet kuin funktiolla Hero. Sen sijaan, että kirjoittaisimme ne tämän funktion sisälle, voimme yksinkertaisesti käskeä JavaScriptiä perimään ne Hero-prototyypistä.

Tämä on mahdollista prototype-ominaisuuden avulla, joka on käytettävissä minkä tahansa objektin sisällä JavaScriptissä.

Sijoittamalla dialogue ominaisuuden Hero.prototype päälle, olemme antaneet sen kaikkien Hero:n instanssien saataville.

Differentiaalinen periytyminen

JavaScriptissa on myös toinen periytymismalli, jota kutsutaan ”differentiaaliseksi periytymiseksi”. Tässä mallissa metodeja ei kopioida vanhemmalta lapselle. Mutta sen sijaan lasten ja niiden vanhemman objektin välillä on yhteys.

Tässä superman:llä ei oikeastaan ole omaa metodia nimeltä dialogue(). Mutta miten superman.dialogue() sitten toimii?

Kun JavaScript-moottori törmää koodissa superman.dialogue():een, se etsii superman-olion sisältä dialogue-nimisen ominaisuuden. Kun se ei löydä sellaista, se etsii prototyyppiketjussa superman:n vanhemman Hero.prototype:n. Sieltä se löytää Hero.prototype.dialogue ja kutsuu sitä this:llä, joka on sidottu superman:ään.

Object.create()

Voimme tehdä tästä vielä eksklusiivisemman luomalla Superman:lle uuden luokan, joka perii Hero:n prototyypin ominaisuudet. Voimme tehdä tämän osoittamalla Superman:n prototyypin Hero:n prototyypille näin:

function Superman() {}
Superman.prototype = Hero.prototype

Mutta tämä tekee vain siitä, että se tekee sekä Superman:sta että Hero:sta samanarvoisia. Se, mitä todella tarvitsemme, on uusi objekti, joka perustuu Hero prototyyppiin. ES5:stä lähtien JavaScriptissä on ollut sisäänrakennettu funktio nimeltä Object.create(). Käytetään sitä tässä alla esitetyllä tavalla:

Superman.prototype = Object.create(Hero.prototype);

Tämä luo uuden tyhjän objektin, joka perustuu Hero-prototyyppiin ja osoittaa sen Superman-prototyyppiin. Kaikki ominaisuudet, jotka meillä on Hero-prototyypissä, ovat nyt käytettävissä Superman-prototyypissä. Joten sen sijaan, että kutsuisimme new Hero, voimme kutsua new Superman ja kaikki toimii edelleen niin kuin pitääkin.

Mutta jos katsot tarkemmin tulostetta, huomaat, että sen sisällä on undefined. Tämä johtuu siitä, että tällä hetkellä Hero on konstruktori vain itselleen. Meidän täytyy call Hero:n ominaisuudet Superman prototyypin sisällä.

function Superman() {
Hero.call(this, 'Superman', 'Clark Kent', 'Krypton')
}

Luotaan toinen konstruktori nimeltä MarvelMovies alla olevan kuvan mukaisesti:

function MarvelMovies(movieName, releaseYear) {
this.movieName = movieName;
this.releaseYear = releaseYear;
}

Kun funktiota käytetään konstruktorina, this viittaa uuteen objektiin, jonka olemme luomassa. Tässä konstruktorissa olen siis ottanut movieName ja releaseYear argumentteina ja osoittanut nämä arvot uuden MarvelMovies-instanssimme avengers ominaisuuksiin movieName ja releaseYear.

var avengers = new MarvelMovies("avengers", 2012);

Luotsen sitten tälle prototyypille uuden metodin nimeltä output alla esitetyllä tavalla:

MarvelMovies.prototype.output = function() {
return "Movie: " + this.movieName + " Released in " + this.releaseYear;
}
console.log(avengers.output());

Tulevaisuuden periytyminen

Periytymisen todella hieno puoli on se, että JavaScriptin avulla voit muokata tai laajentaa luokan ominaisuuksia vielä sen jälkeen, kun olet määrittänyt sen.

Javascripti katselee prototyyppiä yrittäessäsi päästä käsiksi objektin ominaisuuksiin. Voit siis muuttaa luokkia suoritusaikana!

Tämän havainnollistamiseksi luodaan joukko alla olevan kuvan mukaisesti:

var numbers = ;
Array.prototype.shuffle = function() {
return this.sort(function() {
return Math.round( Math.random() * 2) - 1;
});
};
console.log(numbers.shuffle());

Tässä tapauksessa numbers-joukko oli olemassa ennen Array.prototype.shuffle-joukkoa. Mutta JavaScriptissä ominaisuuksien haku menee prototyyppiketjussa ylöspäin. Siksi array saa edelleen pääsyn uuteen metodiin shuffle, koska se on olemassa Array.prototype:ssä, kun me itse asiassa yritämme käyttää sitä.

Yksinkertaisesti sanottuna loimme array:n, sitten palasimme takaisin ja annoimme kaikille Arraysille pääsyn uuteen metodiin.

Vastaa

Sähköpostiosoitettasi ei julkaista.