Rekursive prototypische Vererbung in Javascript?

9
%Vor%

Von Prototypische Vererbung in JavaScript

Ich benutze diesen Code seit einiger Zeit, um neue Objekte zu erstellen, die von früheren Objekten stammen. Ich bin jedoch über eine kleine Überraschung gestolpert.

%Vor%

Beim Versuch, c.foo zu ändern, änderte ich stattdessen a.foo , c.foo zeigt die Änderung an, weil sie von a erbt. Die einzige Lösung, die ich gerade sehe, ist, nur die direkten Eigenschaften von b zu ändern:

%Vor%

Ich bin mir sicher, dass es eine bessere Lösung gibt, die ich vermisse! Wie kann ich neue Objekte aus alten Objekten erstellen, ohne das Original zu verändern?

    
Annan 27.05.2011, 03:22
quelle

5 Antworten

1

+1 für die Referenzierung von Crockford = D

Ich denke, Arrays werden immer als Referenz übergeben, und das Array wird nie kopiert. Ich denke Array.slice würde es kopieren, aber das ist ein Randfall ...

Die create-Funktion wird hauptsächlich zum Kopieren von Funktionen und dergleichen verwendet. Ich benutze diese Methode nie, da ich einfach eine Konstruktorfunktion erstelle:

%Vor%

Auf diese Weise erhalten Sie immer ein neues Array für jeden Anruf. Mach einfach b = new a (); Es funktioniert für mich ...

Ich versuche, Vererbung zu vermeiden, weil es immer Probleme gibt. Ich würde einfach den Konstruktor verwenden und ihm dann neue Variablen zuweisen (nicht den Prototyp). Mehrfachvererbung wird jedoch schwierig ...

    
tjameson 27.05.2011 03:37
quelle
1

Wenn Sie ein neues Objekt von einem Prototyp erstellen, wird kein Kopieren ausgeführt. Nicht einmal die Eigenschaft wird kopiert:

%Vor%

Wenn Sie das tun

%Vor%

Dann ändern Sie nicht die Eigenschaft in F.protoype , Sie fügen eine neue Eigenschaft zu f hinzu:

%Vor%

Dies gilt also für jeden Wert, den Sie einer Eigenschaft zuweisen. Wenn Sie einen Wert klonen wollen, müssen Sie dies explizit tun. Der einfachste Weg besteht darin, einfach eine neue Eigenschaft im Konstruktor zu setzen:

%Vor%

Dieses Problem tritt nur auf, wenn der Prototyp veränderbare Werte enthält, andere Werte können nicht geändert werden (die Eigenschaften können stattdessen Werte ändern).

Und wenn Sie F "ableiten" wollen, denken Sie daran, es vom neuen Konstruktor aus aufzurufen:

%Vor%     
Adam Bergmark 27.05.2011 03:47
quelle
1

Das beste Vererbungsmuster, das ich je gesehen habe, ist das der Google Closure Library. Es basiert auf Konstruktoren. Hier ist ein Beispiel:

%Vor%

Und das Ergebnis ist wie du willst:

%Vor%     
bjornd 27.05.2011 04:08
quelle
0

Nun ja:

1)

%Vor%

Ersetzen Sie Ihre F. Prototype-Referenz von a durch "test", so dass Sie keinen Fehler sehen, aber das ist tatsächlich schlimmer als 2)

2)

%Vor%

ändert das Objekt seit c.foo [0] & amp; a.foo zeigen darauf (sie sind Referenzen / Zeiger auf den a-Wert)

Lösung hier

    
selion 27.05.2011 03:38
quelle
0

Dies ist die Lösung:

%Vor%

Allgemeine Einschränkung dieser Lösung ist, dass Prototypen keine rekursiven Referenzen haben sollten.

Es ist auch möglich, dieses Problem ohne diese Einschränkung zu lösen, aber die Lösung wäre komplizierter. Um die Erstellung von unendlichen rekursiven Objekten zu verhindern, können Sie während des Initialisierungsprozesses eine Art temporären Map-Speicher verwenden. Dieser Speicher wäre Cache-Referenzen zwischen initialisierten Objekten.

    
Ilya Lakhin 27.05.2011 04:07
quelle