Moștenirea
Moștenirea este procesul prin care un obiect poate fi bazat pe un altul. Acest lucru permite obiectelor să împartă proprietățile unul altuia.
Am creat prototipul Hero
și l-am folosit pentru a crea un nou obiect numit superman
. Dar nu facem nimic cu acest obiect. Așa că haideți să ne ocupăm de asta creând o altă funcție numită dialogue
.
function dialogue() {
console.log('I am ' + this.name);
}
Dar dacă executăm codul nostru acum, nu se va întâmpla nimic pentru că această funcție nu știe care este numele real. Pentru aceasta, trebuie să
Vreau ca această nouă funcție să aibă aceleași proprietăți ca și cea din Hero
. În loc să le scriem în interiorul acestei funcții, putem pur și simplu să-i spunem lui JavaScript să le moștenească de la prototipul Hero
.
Acest lucru este posibil cu ajutorul proprietății prototype
care este disponibilă în cadrul oricărui obiect din JavaScript.
Prin plasarea lui dialogue
pe Hero.prototype
, am făcut-o disponibilă tuturor instanțelor lui Hero
.
Modele de moștenire diferențială
JavaScript vine, de asemenea, cu un alt model de moștenire numit „moștenire diferențială”. În acest model, metodele nu sunt copiate de la părinte la copil. Dar, în schimb, există o legătură între copii și obiectul lor părinte.
Aici, superman
nu are de fapt propria metodă numită dialogue()
. Dar atunci cum funcționează superman.dialogue()
?
Când motorul JavaScript întâlnește superman.dialogue()
în cod, el caută proprietatea numită dialogue
în interiorul obiectului superman
. Când nu găsește una, va căuta în lanțul de prototipuri până la părintele Hero.prototype
al lui superman
. Acolo va găsi Hero.prototype.dialogue
și o va apela cu un this
care este legat de superman
.
Object.create()
Potem face acest lucru și mai exclusivist prin crearea unei noi clase pentru Superman
care va moșteni proprietățile prototipului Hero
. Putem face acest lucru prin atribuirea prototipului lui Superman
la prototipul lui Hero
astfel:
function Superman() {}
Superman.prototype = Hero.prototype
Dar ceea ce face acest lucru este că doar face ca atât Superman
cât și Hero
să fie egale. Ceea ce avem cu adevărat nevoie este un nou obiect care să se bazeze pe prototipul Hero
. Începând cu ES5, JavaScript vine cu o funcție încorporată numită Object.create()
. Să o folosim aici, așa cum se arată mai jos:
Superman.prototype = Object.create(Hero.prototype);
Aceasta va crea un nou obiect gol care se bazează pe prototipul Hero
și îl va atribui prototipului Superman
. Astfel, toate proprietățile pe care le avem în prototipul Hero
pot fi acum accesate de prototipul Superman
. Deci, în loc să apelăm new Hero
, putem apela new Superman
și totul va funcționa în continuare așa cum ar trebui.
Dar dacă vă uitați mai atent la ieșire, veți observa că există un undefined
în interiorul ei. Acest lucru se datorează faptului că, în prezent, Hero
este un constructor doar pentru el însuși. Trebuie să call
proprietățile lui Hero
în interiorul prototipului Superman
.
function Superman() {
Hero.call(this, 'Superman', 'Clark Kent', 'Krypton')
}
Să creăm un alt constructor numit MarvelMovies
așa cum se arată mai jos:
function MarvelMovies(movieName, releaseYear) {
this.movieName = movieName;
this.releaseYear = releaseYear;
}
Când o funcție este folosită ca și constructor, this
se referă la noul obiect pe care îl creăm. Deci, în acest constructor, am luat movieName
și releaseYear
ca argumente și am atribuit aceste valori proprietăților movieName
și releaseYear
ale noii noastre instanțe MarvelMovies
numită avengers
.
var avengers = new MarvelMovies("avengers", 2012);
Apoi voi crea o nouă metodă numită output
pentru acest prototip, așa cum se arată mai jos:
MarvelMovies.prototype.output = function() {
return "Movie: " + this.movieName + " Released in " + this.releaseYear;
}
console.log(avengers.output());
Ereditarism viitor
Un aspect cu adevărat grozav al moștenirii este că JavaScript vă permite să modificați sau să extindeți caracteristicile unei clase chiar și după ce ați definit-o.
JavaScript va căuta prototipul atunci când încearcă să acceseze proprietățile unui obiect. Deci, puteți modifica clasele în timpul execuției!
Pentru a ilustra acest lucru, haideți să creăm o matrice așa cum se arată mai jos:
var numbers = ;
Array.prototype.shuffle = function() {
return this.sort(function() {
return Math.round( Math.random() * 2) - 1;
});
};
console.log(numbers.shuffle());
Aici, matricea numbers
a existat înainte ca Array.prototype.shuffle
să existe. Dar în JavaScript, căutările de proprietăți urcă în lanțul prototipurilor. Acesta este motivul pentru care array-ul primește în continuare acces la noua metodă shuffle
, deoarece există pe Array.prototype
atunci când încercăm de fapt să o folosim.
În termeni simpli, am creat un array, apoi ne-am întors și am dat tuturor Array-urilor acces la o nouă metodă.
.