JavaScript jest często błędnie interpretowany jako OJęzyk zorientowany na bject, ale w rzeczywistości to nieprawda; JavaScript to język oparty na prototypach. Dziedziczenie w JavaScript osiąga coś, co nazywa się Prototypowe dziedziczenie. Aby to zrozumieć, najpierw musimy zapoznać się z tym, jak działa konstruktor w JavaScript, w jaki sposób obiekt jest tworzony przeciwko konstruktorowi i co to jest łańcuch prototypowy.
To jeden z zaawansowanych tematów JavaScript, a my zabierzemy Cię bardzo powoli i spróbujemy wyjaśnić każdą odrobinę informacji wraz z fragmentami, zacznijmy.
Jak działa konstruktor w JavaScript
Umownie, Konstruktorzy są specjalnymi funkcjami, które są wykonywane za każdym razem, gdy obiekt jest tworzony w stosunku do klasy; W JavaScript, każde wyrażenie funkcji jest konstruktor. Teraz, jeśli pochodzisz z trywialnego języka programowania i masz tło z programowaniem obiektowym, będziesz się zdezorientować. Dlatego staraj się nie porównywać koncepcji JavaScript z trywialnym programowaniem obiektowym.
Mimo że przybycie wersji JavaScript ES 6 to słowo kluczowe ”Klasa”Dodano do JavaScript, ale nie jest to używane do wdrożenia pojęcia dziedziczenia. W JavaScript możesz tworzyć obiekty zmapowane na funkcję, Tak - Funkcje.
Wyobraź sobie funkcję utworzoną za pomocą następującego kodu:
var person = function ()Jak wspomniano powyżej, że każde wyrażenie funkcji jest konstruktorem, można to udowodnić za pomocą następujących linii wewnątrz funkcji:
var person = funkcja (nazwa)Teraz, jak widać, tworzymy funkcję i wewnątrz ciała funkcji, definiujemy i inicjowujemy właściwości obiektu, tak jak robimy to w każdym normalnym konwencjonalnym konstruktorze. Teraz utwórzmy niektóre obiekty zmapowane na to Osoba Funkcja konstruktora z następującymi wierszami kodu:
var p1 = nowa osoba („John”);Teraz tworzymy obiekty, ale nie mamy metody wewnątrz obiektów, które zwróci nam nazwę osoby, którą właśnie utworzyliśmy, więc stwórzmy tę funkcję w konstruktor Osoba obiekt.
var person = funkcja (nazwa)Teraz musimy wywołać tę funkcję z każdego pojedynczego obiektu za pomocą następujących wierszy kodu:
konsola.Log (P1.getName ());Po uruchomieniu całego fragmentu otrzymujemy następujące dane wyjściowe na konsoli:
Oto główny problem z korzystaniem z tego typu szablonu, wyobraź sobie, że masz 100 obiektów Osoba, Te 100 obiektów będzie miało swoje własny 100 różnych GetName() Funkcje:
Dzieje się tak, ponieważ te obiekty są instancjami Osoba, dzięki czemu jest zbędne na pamięci. To tutaj Właściwość prototypowa wchodzi w grę.
Właściwość prototypowa
Każda funkcja i każdy obiekt ma nazwaną właściwość Prototyp, Ten prototyp zawiera metody i właściwości funkcji, a ta prototypowa właściwość jest udostępniana między wszystkimi instancją/obiektami, które są odwzorowane na funkcję, spójrz na ten fragment:
Gdybyśmy utworzyli niektóre obiekty na podstawie tej funkcji „X”, Dziedziczą metody i właściwości w„prototyp”Funkcji. W naszym przykładzie główną funkcją byłaby Osoba A obiekty są P1, P2, tak jak:
Korzystanie z właściwości prototypowej do tworzenia prototypowego dziedziczenia
Naszym głównym problemem z trywialnym podejściem było to, że każdy obiekt miał swój własny GetName() funkcje, im bardziej obiekty, tym więcej jest liczbą GetName() Funkcje w pamięci. Aby to usunąć, piszemy funkcja getName () poza wyrażeniem konstruktora i wewnątrz właściwości prototypowej za pomocą składni:
nazwa obiektu.prototyp.MethodNameNasz kod zmienia się w:
var person = funkcja (nazwa)Wyjście jest dokładnie takie samo jak ostatni raz:
Ale tym razem różnica polega na tym, że zamiast każdego obiektu mającego własny GetName() Funkcja, każdy obiekt uzyskuje dostęp do GetName() Funkcja w swoim nadrzędnym i używającą tej funkcji do wykonania podanej instrukcji. To się nazywa "Prototypowe dziedziczenie„W JavaScript. W końcu nie czyni go zbędnym w pamięci.
Obiekt główny
Wszystko w JavaScript jest zasadniczo obiektem, oznacza to, że wszystko w JavaScript opiera się Obiekt (z kapitałem o).
Aby to wyjaśnić, użyj następujących wierszy kodu i otwórz konsolę przeglądarki.
var demo = function ()Tworzysz funkcję z pustym konstruktorem i konsola.reż() Wyświetla szczegóły próbny() Definicja funkcji na konsoli, zobaczysz to:
Rozwiń małą grot strzałki i zbadaj __proto__ właściwość tej funkcji, __proto__ Właściwość mówi nam o tym, jaki obiekt został zmapowany na tę funkcję, zobaczysz to:
Teraz stwórzmy instancję tej funkcji demo i zbadajmy jej __proto__ tak jak:
var demo = function ()Po uruchomieniu tego kodu należy zobaczyć następujące dane wyjściowe na konsoli:
Rozwiń to i zbadaj konstruktor, na który zmapowano instancję „X”, zobaczysz:
Co oznacza ten obiekt X ma demo rodzica i już wiemy, że Demo funkcjijest mapowany na obiekt JavaScript. To tworzy łańcuch prototypowy jako:
Obiekt "X”Może uzyskać dostęp do metod i właściwości obiektu głównego, tworząc w ten sposób łańcuch spadku.
Jeśli po raz ostatni spojrzymy w naszej konsoli, możemy zbadać, że obiekt główny ma tę jedną metodę w swojej prototypowej właściwości ToString () Jak:
I nazywamy tę właściwość na obiekcie „X”I na funkcji próbny że stworzyłeś jako:
konsola.Log (x.ToString ());Otrzymujesz wyjście jako:
Widać, zarówno obiekt, jak i funkcja były w stanie uzyskać dostęp do tej metody, nawet jeśli nie została w nich zdefiniowana.
Tak działa dziedzictwo w JavaScript przez prototypy.
Wniosek
Dziedziczenie w JavaScript bardzo różni się od naszej konwencjonalnej definicji dziedziczenia w programowaniu obiektowym. W JavaScript osiągamy dziedzictwo za pomocą właściwości o nazwie prototyp. Nauczyłeś się, jak działa konstruktor w JavaScript, czym jest prototyp właściwość, jak wszystko w JavaScript jest obiektem, poznając się Obiekt główny. Ponadto dowiedziałeś się o prototypowym dziedziczeniu i wiązaniu prototypów, a ty byłeś w stanie uzyskać dostęp do metod i właściwości Obiekt główny używając obiekt że stworzyłeś.