Zrozumienie prototypowego dziedziczenia w JavaScript

Dziedziczenie

Dziedziczenie jest procesem, przez który jeden obiekt może być oparty na innym. Pozwala to obiektom dzielić wzajemnie swoje właściwości.

Utworzyłem prototyp Hero i użyłem go do utworzenia nowego obiektu o nazwie superman. Ale my nic nie robimy z tym obiektem. Zajmijmy się więc tym, tworząc kolejną funkcję o nazwie dialogue.

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

Ale jeśli teraz uruchomimy nasz kod, nic się nie stanie, ponieważ ta funkcja nie wie, jaka naprawdę jest nazwa. W tym celu musimy

Chcę, aby ta nowa funkcja miała te same właściwości, co funkcja Hero. Zamiast zapisywać je wewnątrz tej funkcji, możemy po prostu powiedzieć JavaScriptowi, aby odziedziczył je z prototypu Hero.

Jest to możliwe za pomocą właściwości prototype, która jest dostępna wewnątrz każdego obiektu w JavaScript.

Przez umieszczenie dialogue na Hero.prototype, udostępniliśmy ją wszystkim instancjom Hero.

Dyfferencyjne dziedziczenie

JavaScript posiada również inny model dziedziczenia zwany „dziedziczeniem różnicowym”. W tym modelu, metody nie są kopiowane z rodzica do dziecka. Ale zamiast tego istnieje związek między dziećmi i ich obiektem nadrzędnym.

Tutaj, superman w rzeczywistości nie ma swojej własnej metody o nazwie dialogue(). Ale w takim razie jak działa superman.dialogue()?

Kiedy silnik JavaScript natrafia w kodzie na superman.dialogue(), szuka właściwości o nazwie dialogue wewnątrz obiektu superman. Gdy jej nie znajdzie, zajrzy w górę łańcucha prototypów do rodzica superman Hero.prototype. Tam znajdzie Hero.prototype.dialogue i wywoła go za pomocą this, który jest związany z superman.

Object.create()

Możemy uczynić to jeszcze bardziej ekskluzywnym, tworząc nową klasę dla Superman, która będzie dziedziczyć właściwości prototypu Hero. Możemy to zrobić przypisując prototyp Superman do prototypu Hero w ten sposób:

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

Ale to, co to robi, to po prostu czyni oba Superman i Hero równymi. To, czego naprawdę potrzebujemy, to nowy obiekt, który jest oparty na prototypie Hero. Od ES5, JavaScript posiada wbudowaną funkcję o nazwie Object.create(). Użyjmy jej tutaj, jak pokazano poniżej:

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

To stworzy nowy pusty obiekt, który jest oparty na prototypie Hero i przypisze go do prototypu Superman. Tak więc wszystkie właściwości, które mamy w prototypie Hero mogą być teraz dostępne dla prototypu Superman. Zamiast więc wywoływać new Hero, możemy wywołać new Superman i wszystko nadal będzie działać tak, jak powinno.

Jeśli jednak przyjrzysz się dokładniej danym wyjściowym, zauważysz, że w środku znajduje się undefined. Dzieje się tak dlatego, że obecnie Hero jest konstruktorem tylko dla siebie. Musimy call właściwości Hero wewnątrz Superman prototypu.

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

Utwórzmy kolejny konstruktor o nazwie MarvelMovies, jak pokazano poniżej:

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

Gdy funkcja jest używana jako konstruktor, this odnosi się do nowego obiektu, który tworzymy. Tak więc w tym konstruktorze, wziąłem movieName i releaseYear jako argumenty i przypisałem te wartości do właściwości movieName i releaseYear naszej nowej instancji MarvelMovies o nazwie avengers.

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

Następnie utworzę nową metodę o nazwie output dla tego prototypu, jak pokazano poniżej:

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

Przyszłe dziedziczenie

Naprawdę wspaniałym aspektem dziedziczenia jest to, że JavaScript pozwala ci modyfikować lub rozszerzać właściwości klasy nawet po jej zdefiniowaniu.

JavaScript będzie szukał prototypu przy próbie dostępu do właściwości obiektu. Tak więc, możesz zmieniać klasy w czasie wykonywania!

Aby to zilustrować, utwórzmy tablicę, jak pokazano poniżej:

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

Tutaj, tablica numbers istniała przed tablicą Array.prototype.shuffle. Ale w JavaScript, wyszukiwania właściwości idą w górę łańcucha prototypów. To dlatego tablica wciąż uzyskuje dostęp do nowej metody shuffle, ponieważ istnieje na Array.prototype, gdy faktycznie próbujemy jej użyć.

W prostych słowach, stworzyliśmy tablicę, a następnie cofnęliśmy się i daliśmy wszystkim tablicom dostęp do nowej metody.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.