W PHP / Java można:
class Sub extends Base
{
}
I automatycznie wszystkie publiczne / chronione metody, właściwości, pola itp. Klasy Super stają się częścią klasy Sub, którą można w razie potrzeby przesłonić.
Jaki jest odpowiednik tego w Javascript?
javascript
oop
Kliknij opcję Głos za
źródło
źródło
Odpowiedzi:
Zmieniłem sposób, w jaki teraz to robię, staram się unikać używania funkcji konstruktorów i ich
prototype
właściwości, ale moja stara odpowiedź z 2010 roku wciąż jest na dole. Teraz wolęObject.create()
.Object.create
jest dostępny we wszystkich nowoczesnych przeglądarkach.Powinienem zauważyć, że
Object.create
jest to zwykle znacznie wolniejsze niż użycienew
z konstruktorem funkcji.jsfiddle
Jedną z największych zalet korzystania z Object.create jest możliwość przekazania argumentu defineProperties , który zapewnia znaczną kontrolę nad tym, jak można uzyskać dostęp do właściwości w klasie i nad nimi wyliczać, a także używam funkcji do tworzenia instancji, służą one jako konstruktorów w taki sposób, jak można wykonać inicjalizację na końcu zamiast po prostu zwrócić instancję.
jsfiddle
Oto moja oryginalna odpowiedź z 2010 roku:
źródło
alert()
aby zobaczyć, jakieinstance.showColor()
zwroty nadal otrzymujęundefined
. jsbin.com/uqalin/1W JavaScript nie masz klas, ale możesz uzyskać dziedziczenie i ponowne wykorzystanie zachowań na wiele sposobów:
Dziedziczenie pseudoklasyczne (poprzez prototypowanie):
Powinien być używany z
new
operatorem:Aplikacja funkcji lub „łańcuch konstruktora”:
Takie podejście należy również zastosować w przypadku
new
operatora:Różnica w porównaniu z pierwszym przykładem jest to, że kiedy konstruktor do wnętrza obiektu , dodaje właściwości przypisane na bezpośrednio na nową instancję np zawiera właściwości i bezpośrednio ( ).
apply
Super
this
Sub
this
Super
subInstance
member1
member2
subInstance.hasOwnProperty('member1') == true;
W pierwszym przykładzie te właściwości są osiągane przez łańcuch prototypów , istnieją w
[[Prototype]]
obiekcie wewnętrznym .Dziedziczenie pasożytnicze lub konstruktorzy mocy:
To podejście opiera się w zasadzie na „rozszerzaniu obiektów”, nie musisz używać
new
operatora i jak widać,this
słowo kluczowe nie jest używane.ECMAScript 5th Ed.
Object.create
metoda:Powyższa metoda jest prototypową techniką dziedziczenia zaproponowaną przez Crockforda .
Instancje obiektów dziedziczą po innych instancjach obiektów, to wszystko.
Technika ta może być lepiej niż proste „obiekt powiększania”, ponieważ odziedziczone właściwości nie są kopiowane wszystkich nowych instancji obiektów, ponieważ baza obiekt jest ustawiony jak
[[Prototype]]
z rozszerzonego przedmiotu, w powyższym przykładziesubInstance
zawiera fizycznie tylkomember3
nieruchomości.źródło
Object.create()
lubclone()
funkcji niestandardowej (np. mercurial.intuxication.org/hg/js-hacks/raw-file/tip/clone.js ), aby dziedziczyć bezpośrednio z obiektu prototypowego; zobacz komentarze do stackoverflow.com/questions/1404559/ ... po wyjaśnienieObject.create
metodzie :)member1
zmienną, co w ogóle nie jest pożądane. Oczywiście mogą to przepisać, ale to po prostu nie ma sensu. github.com/dotnetwise/Javascript-FastClass to lepsze rozwiązanie dla cukru.Sub.prototype = new Super();
. A jeśli obie klasy nigdy nie będą używane podczas wykonywania skryptu? Wygląda na problem z wydajnością. Dlaczego muszę tworzyć klasę nadrzędną, jeśli klasa podrzędna nie jest faktycznie używana? Czy możesz to rozwinąć? Oto prosta demonstracja problemu: jsfiddle.net/slavafomin/ZeVL2 Dzięki!Dla tych, którzy dotrą na tę stronę w 2019 roku lub później
W najnowszej wersji standardu ECMAScript (ES6) można użyć słowa kluczowego
class
.Zauważ, że definicja klasy nie jest regularna
object
; dlatego nie ma przecinków między członkami klasy. Aby utworzyć instancję klasy, musisz użyćnew
słowa kluczowego. Aby dziedziczyć z klasy bazowej, użyjextends
:Aby dziedziczyć z klasy bazowej, użyj
extends
:Z klasy pochodnej możesz użyć super z dowolnego konstruktora lub metody, aby uzyskać dostęp do jej klasy bazowej:
super().
super.getName()
.Korzystanie z klas to nie wszystko. Jeśli chcesz zagłębić się w temat, polecam „ Zajęcia w ECMAScript 6 ” dr Axela Rauschmayera. *
źródło
źródło
class
iextends
jest (bardzo przydatnym) cukrem składniowym dla łańcucha prototypów: stackoverflow.com/a/23877420/895245Cóż, w JavaScript nie ma „dziedziczenia klas”, jest tylko „dziedziczenie prototypów”. Więc nie tworzysz klasy „ciężarówki”, a następnie oznaczasz ją jako podklasę „samochód”. Zamiast tego tworzysz obiekt „Jack” i mówisz, że używa on „John” jako prototypu. Jeśli John wie, ile wynosi „4 + 4”, to Jack też to wie.
Sugeruję przeczytanie artykułu Douglasa Crockforda o dziedziczeniu prototypowym tutaj: http://javascript.crockford.com/prototypal.html . Pokazuje on również, jak sprawić, by JavaScript miał dziedziczenie „podobne”, jak w innych językach OO, a następnie wyjaśnia, że to w rzeczywistości oznacza złamanie javaScript w sposób, w jaki nie był przeznaczony.
źródło
Uważam, że ten cytat jest najbardziej pouczający:
Lubię używać konstruktorów, a nie obiektów, więc jestem zwolennikiem metody "pseudo-klasycznego dziedziczenia" opisanej tutaj przez CMS . Oto przykład wielokrotnego dziedziczenia z łańcuchem prototypów :
Oto kolejny dobry zasób z MDN , a tutaj jest jsfiddle, więc możesz go wypróbować .
źródło
Dziedziczenie JavaScript różni się nieco od Javy i PHP, ponieważ tak naprawdę nie ma klas. Zamiast tego ma obiekty prototypowe, które udostępniają metody i zmienne składowe. Możesz łączyć te prototypy, aby zapewnić dziedziczenie obiektów. Najpopularniejszy wzorzec, jaki znalazłem podczas badania tego pytania, jest opisany w sieci Mozilla Developer Network . Zaktualizowałem ich przykład, aby zawierał wywołanie metody nadklasy i pokazywał dziennik w komunikacie ostrzegawczym:
Osobiście uważam, że dziedziczenie w Javascript jest niezręczne, ale to najlepsza wersja, jaką znalazłem.
źródło
nie możesz (w klasycznym sensie). Javascript jest językiem prototypowym. Zauważysz, że nigdy nie deklarujesz „klasy” w Javascript; definiujesz jedynie stan i metody obiektu. Aby stworzyć dziedziczenie, bierzesz jakiś obiekt i prototypujesz go. Prototyp zostaje rozbudowany o nową funkcjonalność.
źródło
Możesz użyć
.inheritWith
i.fastClass
biblioteki . Jest szybszy niż większość popularnych bibliotek, a czasem nawet szybszy niż wersja natywna.Bardzo łatwy w użyciu:
Stosowanie
źródło
źródło
Po przeczytaniu wielu postów wymyśliłem to rozwiązanie ( tutaj jsfiddle ). Przez większość czasu nie potrzebuję czegoś bardziej wyrafinowanego
źródło
Dzięki odpowiedzi CMS i po pewnym czasie bawiąc się prototypem i Object.create, a co nie, udało mi się wymyślić zgrabne rozwiązanie dla mojego dziedziczenia za pomocą aplikacji, jak pokazano tutaj:
źródło
Od ES2015 dokładnie tak robi się dziedziczenie w JavaScript
źródło
źródło
Klasy ES6:
Javascript nie ma klas. Klasy w javascript są po prostu cukrem składniowym opartym na prototypowego wzorca dziedziczenia , który javascript. Możesz użyć JS
class
do wymuszenia dziedziczenia prototypów, ale ważne jest, aby zdać sobie sprawę, że nadal używasz funkcji konstruktora pod maską.Pojęcia te mają również zastosowanie, gdy rozszerzasz z
es6
klasy za pomocą słowa kluczowego extends. To po prostu tworzy dodatkowe łącze w łańcuchu prototypów. Plik__proto__
Przykład:
Object.create ()
Object.create()
to także sposób na tworzenie dziedziczenia w JS w javascript.Object.create()
jest funkcją, która tworzy nowy obiekt, jako argument przyjmuje istniejący obiekt. Przydzieli obiekt, który został odebrany jako argument, do__proto__
właściwości nowo utworzonego obiektu. Ponownie ważne jest, aby zdać sobie sprawę, że jesteśmy związani prototypowym paradygmatem dziedziczenia, który ucieleśnia JS.Przykład:
źródło
Nie możesz dziedziczyć z klasy w JavaScript, ponieważ w JavaScript nie ma klas.
źródło