prototypisches Vererbungskonzept in JavaScript als prototypische Sprache

8

Sie wissen, dass Javascript eine prototypbasierte Programmiersprache ist.
Ich habe einige Bücher über Javascript und sein prototypisches Vererbung Konzept gelesen, aber:

"Wenn du es einem Sechsjährigen nicht erklären kannst, verstehst du es wirklich nicht selbst." Nun, ich habe versucht, einem 22-jährigen Freund ein JavaScript-Prototyp-Konzept zu erklären, und es ist völlig fehlgeschlagen!

Wie würdest du es einer 6-jährigen Person erklären, die sich sonderbar für dieses Thema interessiert? Ich habe einige Beispiele in Stack Overflow gesehen, und es hat nicht geholfen.

    
Dariush Jafari 30.08.2012, 16:06
quelle

6 Antworten

2

Anders als die meisten anderen objektorientierten Sprachen hat JavaScript kein Konzept von Klassen. In den meisten anderen objektorientierten Sprachen würden Sie eine Instanz einer bestimmten Klasse instanziieren, in JavaScript ist dies jedoch nicht der Fall.
In JavaScript können Objekte neue Objekte erstellen, und Objekte können von anderen Objekten erben / stark>
Dieses ganze Konzept wird prototypische Vererbung genannt.

aber wie können wir ein Objekt machen?
Sie können einfach ein generisches Objekt mit {} erstellen.

%Vor%

Sie können keine Instanz von a erstellen, da dies keine Funktion ist. mit anderen Worten, es hat keine spezielle interne Methode [[Construct]] .

In JavaScript kann jede Funktion auch als Objekt instanziiert werden. Die folgende Funktion ist eine einfache Funktion, die einen Namen erhält und im aktuellen Kontext speichert:

%Vor%

Wir können sehen, dass User eine Instanz von Function ist:

%Vor%

Erstellen Sie eine neue Instanz dieser Funktion mit dem angegebenen Namen:

%Vor%

Wir können sehen, dass sein name als eine Eigenschaft von sich selbst gesetzt wurde:

%Vor%

Und das ist eine Instanz des User -Objekts:

%Vor%

Nun, da User() nur eine Funktion ist, was passiert, wenn wir es so behandeln?

%Vor%

Da sein this -Kontext nicht festgelegt wurde, wird standardmäßig das globale window -Objekt verwendet, dh window.name entspricht dem bereitgestellten name :

%Vor%

Die Eigenschaft constructor existiert für jedes Objekt und verweist immer auf die Funktion, die sie erstellt hat. Auf diese Weise sollten Sie in der Lage sein, das Objekt effektiv zu duplizieren, indem Sie ein neues Objekt derselben Basisklasse, aber nicht mit denselben Eigenschaften erstellen. Ein Beispiel dafür ist unten zu sehen:

%Vor%

Wir können sehen, dass die Konstruktoren tatsächlich die gleichen sind:

%Vor%

Prototyp und öffentliche Methoden

Prototyp enthält einfach ein Objekt, das als Basisreferenz für alle neuen Kopien seines übergeordneten Objekts dient. Im Prinzip ist jede Eigenschaft des Prototyps für jede Instanz dieses Objekts verfügbar. Dieser Erstellungs- / Referenzprozess gibt uns eine billige Version der Vererbung.
Da ein Objektprototyp nur ein Objekt ist, können Sie ihm wie jedem anderen Objekt neue Eigenschaften hinzufügen. Das Hinzufügen neuer Eigenschaften zu einem Prototyp macht sie zu einem Teil jedes Objekts, das vom ursprünglichen Prototyp instanziiert wird, wodurch alle Eigenschaften tatsächlich veröffentlicht werden. Beispiel:

%Vor%

Das Hinzufügen von Methoden und Eigenschaften zur prototyp -Eigenschaft der Konstruktorfunktion ist eine weitere Möglichkeit, den Objekten, die dieser Konstruktor erzeugt, Funktionalität hinzuzufügen. Fügen wir eine weitere Eigenschaft, CardNo und eine getName() Methode hinzu:

%Vor%

Und fügen Sie dem Prototyp eine weitere Funktion hinzu. Beachten Sie, dass der Kontext innerhalb des instanziierten Objekts liegt.

%Vor%

Instanziieren Sie ein neues Benutzerobjekt:

%Vor%

Wir können sehen, dass die beiden Methoden, die wir anhängen, mit dem Objekt zusammenhängen:

%Vor%

So hat jede Funktion in Javascript eine Prototypeigenschaft. Der Anfangswert ist ein leeres Objekt ({}). Beachten Sie, dass generische Objekte (keine Funktionen) nicht die Prototypeigenschaft haben:

%Vor%

Delegation

Wenn Sie versuchen, auf eine Eigenschaft von user , sagen user.name , zuzugreifen, durchsucht die JavaScript-Engine alle Eigenschaften des Objekts nach einem namens name und gibt, falls es gefunden wird, ihren Wert zurück :

%Vor%

Was passiert, wenn die Javascript-Engine die Eigenschaft nicht finden kann? Er identifiziert den Prototyp der Konstruktorfunktion , die zum Erstellen dieses Objekts verwendet wurde (wie bei user.constructor.prototype ). Wenn die Eigenschaft im Prototyp gefunden wird, wird diese Eigenschaft verwendet:

%Vor%

und so ...
Wenn Sie zwischen den Eigenschaften des Objekts und den Eigenschaften des Prototyps unterscheiden möchten, verwenden Sie hasOwnProperty() . Probieren Sie:

%Vor%

Private Methoden

Wenn Sie eine Eigenschaft für eine Funktion direkt festlegen, wird sie privat sein. Beispiel:

%Vor%

Privilegierte Methoden

Privilegierte Methoden ist ein Begriff, der von Douglas Crockford geprägt wurde, um sich auf Methoden zu beziehen, die fähig sind um private Variablen (innerhalb eines Objekts) anzuzeigen und zu manipulieren, während auf sie weiterhin zugegriffen werden kann Benutzer als öffentliche Methode. Beispiel:
Erstellen Sie einen neuen Benutzerobjektkonstruktor:

%Vor%

Erstellen Sie eine neue Instanz des Benutzerobjekts:

%Vor%

Überprüfen Sie, ob das zurückgegebene Jahr korrekt ist:

%Vor%

Beachten Sie, dass wir nicht auf die private Jahr-Eigenschaft des Objekts zugreifen können:

%Vor%

Im Wesentlichen sind privilegierte Methoden dynamisch generierte Methoden, weil sie hinzugefügt werden zu dem Objekt zur Laufzeit, anstatt wenn der Code zum ersten Mal kompiliert wird. Obwohl diese Technik rechenintensiver ist als das Binden einer einfachen Methode an den Objektprototyp, ist sie auch viel leistungsfähiger und flexibler.

Statische Methoden

Die Voraussetzung für statische Methoden ist praktisch identisch mit der anderer normaler Funktionen.Der Hauptunterschied besteht jedoch darin, dass die Funktionen als statische Eigenschaften eines Objekts existieren. Als Eigenschaft sind sie im Kontext einer Instanz dieses Objekts nicht zugänglich; Sie sind nur im selben Kontext wie das Hauptobjekt selbst verfügbar. Für diejenigen, die mit der traditionellen klassenähnlichen Vererbung vertraut sind, ist dies eine Art statische Klassenmethode In Wirklichkeit ist der einzige Vorteil, Code auf diese Weise zu schreiben, darin, die Objektnamespaces sauber zu halten.
Eine statische Methode, die an das Benutzerobjekt angehängt ist:

%Vor%

Auf die Funktion cloneUser kann nur von User zugegriffen werden:

%Vor%     
Dariush Jafari 31.08.2012, 04:33
quelle
8

Bei der klassischen Vererbung geht es um die Erweiterung von Arten von Dingen. Angenommen, Sie haben eine Klasse wie Bike . Wenn Sie das Verhalten erweitern möchten, müssen Sie einen neuen Typ von Fahrrad (wie MotorBike ) entwerfen.

Es ist wie eine Fabrik zu bauen - Sie machen viele Blaupausen und Baupläne, die auf diese Blaupausen verweisen, aber um einen zu bauen, müssen Sie den Bauplan nehmen und daraus etwas machen.

Bei der prototypbasierten Vererbung geht es darum, die Dinge selbst zu erweitern. Angenommen, Sie können Bike -Objekte erstellen. Du nimmst einen dieser% s in deine Garage und schnallst dir einen Düsenmotor an.

Dies entspricht nicht dem Bauplan. Das ist etwas, was du mit diesem speziellen Motorrad gemacht hast. Aber deine Freunde sehen deinen Apparat und wollen auch einen. Anstatt also einen Entwurf für Ihr neues Design zu erstellen, klicken Sie auf ein Schild mit der Aufschrift " Bike factory" und fangen einfach an, mehr davon zu machen. Und jedes Mal, wenn Sie sich nicht daran erinnern können, wie etwas zusammenpasst, sehen Sie sich nicht nur einen Entwurf an, sondern auch Ihr Original-Fahrrad. Dein ursprüngliches Fahrrad ist das Prototyp Fahrrad, und alle neuen Fahrräder basieren darauf.

Nun, für einen echten 6-Jährigen würde ich wahrscheinlich aufhören (wenn ich sie nicht schon verloren hätte), aber in Wirklichkeit baut die prototypbasierte Vererbung nicht nur Kopien auf, sondern macht sogar etwas Cooler - es verbindet die neuen JetBike -Objekte tatsächlich mit dem originalen Prototyp-Bike, das du in deiner Garage hast. Wenn Sie die Federung an Ihrem Prototyp-Fahrrad ersetzen, dann werden alle Fahrräder Ihrer Freunde auch ihre Federung magisch ersetzt haben.

Sehen wir uns einen JS-ischen Pseudocode an:

%Vor%     
cloudfeet 30.08.2012 16:52
quelle
2

Javascript ist eine objektorientierte Sprache, die insofern einzigartig ist, als sie keine Klassen hat. Stattdessen verwenden wir Funktionen zum Erstellen von Objekten.

Alle Funktionen haben einen Prototyp, von dem alle Objekte, die Sie mit dieser Funktion erstellen, alle Eigenschaften und Methoden übernehmen. Da Javscript keine Klassen enthält, führen Sie die Vererbung mit einem tatsächlichen Objekt durch, von dem Sie übernehmen (im Gegensatz zu einer Klasse). Sie können den Prototyp einer Funktion auf ein Objekt setzen, sodass alle Objekte, die Sie mit dieser Funktion erstellen, alle Methoden und Eigenschaften des Prototypobjekts der Funktion erben.

Wenn ich also eine Funktion habe, die ein Objekt erzeugt:

%Vor%

Sie können eine andere Funktion erstellen, die ein Objekt erstellt und es zulässt, dass Eigenschaften und Methoden eines Objekts übernommen werden, indem der Prototyp der Funktionen auf dieses Objekt gesetzt wird.

%Vor%

Dann können Sie auf alle Sachen zugreifen, die vererbt wurden.

%Vor%     
dqhendricks 30.08.2012 17:04
quelle
1

Interessante Herausforderung: -)

Erstens würde ich niemals versuchen, es jemandem zu erklären, indem ich nur Wörter verwende, aber ich werde es versuchen :-)

"Prototypische Vererbung ist wie ein Pokemon, das Kräfte von anderen Pokemons stehlen kann."

Denk daran, dass du dein eigenes Pokemon erstellen kannst. Sie können entscheiden, wie groß es ist, welche Farbe es ist usw. (Konstruktor). Dann kannst du diese Pokemon-Kräfte (Prototypen) geben. Sie können so viele dieser Pokemons spawnen, wie Sie möchten. Was prototypische Vererbung gibt, ist die Möglichkeit, dass ein, mehrere oder alle diese Pokemons Kräfte von anderen Pokemons stehlen können. Du kannst sogar Pokemons Kräfte stehlen, die bereits Kräfte von einem anderen Pokemon gestohlen haben. Dies schafft eine ganze Reihe von superstarken Pokemons.

Vielleicht ein bisschen albern, aber es spiegelt wider, wie leistungsfähig die prototypische Vererbung ist ... im Pokémon Sinn: -)

    
Christian Jørgensen 30.08.2012 17:24
quelle
1

Prototypische Vererbung ist wie ein Sohn, der seinen Vater auf dem Rücken trägt, wohin er auch geht. Wenn jemand den Sohn fragt: "Welche Farbe haben deine Schuhe?" Er würde mit seiner Schuhfarbe antworten, wenn er nicht barfuß ist, dann würde er mit seiner Schuhfarbe antworten.

    
ssoward 19.07.2013 20:24
quelle
0
%Vor%     
Rajbir Sharma 15.11.2016 12:46
quelle