Angenommen, Sie haben den folgenden Code:
function A() {
function modify() {
x = 300;
y = 400;
}
var c = new C();
}
function B() {
function modify(){
x = 3000;
y = 4000;
}
var c = new C();
}
C = function () {
var x = 10;
var y = 20;
function modify() {
x = 30;
y = 40;
};
modify();
alert("The sum is: " + (x+y));
}
Nun ist die Frage, ob es eine Möglichkeit ist , in dem ich die Methode außer Kraft setzen kann modify
von C
den Methoden, die in A
und B
. In Java würden Sie das super
Schlüsselwort -key verwenden, aber wie können Sie so etwas in JavaScript erreichen?
javascript
oop
overriding
Daniel Nastase
quelle
quelle
modify
ist keine Methode, sondern eine verschachtelte Funktion - es gibt einen Unterschied zwischen diesen beiden ...super
Schlüsselwort, um auf die nicht privaten Felder und Methoden einer Superklasse zuzugreifen . Sie verwenden es nicht, um sie zu überschreiben.Antworten:
Bearbeiten: Es ist nun sechs Jahre her, dass die ursprüngliche Antwort geschrieben wurde und sich viel geändert hat!
Viel Glück!
Die JavaScript-Vererbung sieht etwas anders aus als Java. So sieht das native JavaScript-Objektsystem aus:
Leider ist dies ein bisschen hässlich und beinhaltet keinen sehr guten Weg zu "super": Sie müssen manuell angeben, welche Methode der übergeordneten Klassen Sie aufrufen möchten. Infolgedessen gibt es eine Vielzahl von Werkzeugen, um das Erstellen von Klassen zu vereinfachen. Schauen Sie sich Prototype.js, Backbone.js oder eine ähnliche Bibliothek an, die eine schönere Syntax für OOP in js enthält.
quelle
Da dies ein Top-Hit bei Google ist, möchte ich eine aktualisierte Antwort geben.
Die Verwendung von ES6-Klassen erleichtert das Überschreiben von Vererbung und Methoden erheblich:
Das
super
Schlüsselwort bezieht sich auf die übergeordnete Klasse, wenn es in der ererbenden Klasse verwendet wird. Außerdem sind alle Methoden in der übergeordneten Klasse an die Instanz des untergeordneten Elements gebunden, sodass Sie nicht schreiben müssensuper.method.apply(this);
.In Bezug auf die Kompatibilität: In der ES6-Kompatibilitätstabelle werden (meistens) nur die neuesten Versionen der Support-Klassen der Hauptakteure angezeigt. V8-Browser haben sie seit Januar dieses Jahres (Chrome und Opera), und Firefox, das die SpiderMonkey JS-Engine verwendet, wird nächsten Monat Klassen mit ihrer offiziellen Firefox 45-Version sehen. Auf der mobilen Seite unterstützt Android diese Funktion immer noch nicht, während iOS 9, das vor fünf Monaten veröffentlicht wurde, teilweise unterstützt wird.
Glücklicherweise gibt es Babel , eine JS-Bibliothek zum erneuten Kompilieren von Harmony-Code in ES5-Code. Klassen und viele andere coole Funktionen in ES6 können Ihren Javascript-Code viel lesbarer und wartbarer machen.
quelle
Einmal sollte es vermieden werden, klassisches OO zu emulieren, und stattdessen prototypisches OO verwenden. Eine schöne Utility-Bibliothek für prototypische OO sind Merkmale .
Anstatt Methoden zu überschreiben und Vererbungsketten einzurichten (man sollte immer die Objektzusammensetzung der Objektvererbung vorziehen), sollten Sie wiederverwendbare Funktionen in Merkmalen bündeln und damit Objekte erstellen.
Live-Beispiel
quelle
modify () ist in Ihrem Beispiel eine private Funktion, auf die nur innerhalb Ihrer A-, B- oder C-Definition zugegriffen werden kann. Sie müssten es als deklarieren
C hat keinen Verweis auf seine Eltern, es sei denn, Sie übergeben es an C. Wenn C so eingerichtet ist, dass es von A oder B erbt, erbt es seine öffentlichen Methoden (nicht seine privaten Funktionen, wie Sie sie modifiziert haben ()). Sobald C Methoden von seinem übergeordneten Element erbt, können Sie die geerbten Methoden überschreiben.
quelle
Die Methode
modify()
, die Sie zuletzt aufgerufen haben, wird im globalen Kontext aufgerufen, wenn Sie überschreiben möchten, müssenmodify()
Sie zuerstA
oder erbenB
.Vielleicht versuchen Sie das:
In diesem Fall
C
erbtA
quelle
C.prototype.modify()
hätte den falschenthis
Wert. Das heißt ,C.prototype
statt der Instanz von c. Bitte verwenden Sie,.call(this)
aber dann ist Ihre Antwort nur ein Duplikat :)Nicht, wenn Sie nicht alle Variablen "öffentlich" machen, dh sie
Function
entweder direkt oder über dieprototype
Eigenschaft zu Mitgliedern der machen .Sie werden einige Änderungen bemerken.
Am wichtigsten ist, dass der Aufruf des vermeintlichen Konstruktors "Superklassen" jetzt in dieser Zeile impliziert ist:
Beide
A
undB
werden nun individuell veränderbare Mitglieder habenx
undy
was nicht der Fall wäre, wenn wir... = C
stattdessen geschrieben hätten .Dann
x
,y
undmodify
alle „öffentlichen“ Mitglieder , so dass eine andere Zuordnung vonFunction
ihnenüberschreibt das Original
Function
mit diesem Namen.Schließlich kann der Aufruf von
modify
in derFunction
Deklaration nicht ausgeführt werden, da der implizite Aufruf der "Superklasse" dann erneut ausgeführt wird, wenn wir die vermeintliche "Oberklasse" auf dieprototype
Eigenschaft der angeblichen "Unterklassen" setzen.Aber so würden Sie mehr oder weniger so etwas in JavaScript machen.
HTH,
FK
quelle
<name>.prototype = new C;
sowieso keinen Sinn , alle Mitglieder des Prototyps zu beschattenObjects
, teilen sich alle Erben dasselbe Mitglied . Also ändernC
C
x
inA
würde sich ändernx
inC
und damit ändernx
inB
. Welches ist offensichtlich unerwünscht.A
undB
erben vonC
. Wenn diese Zeile fehlen würde, wäre dies nicht der Fall. Tatsächlich wäre in diesem Fall der einzige Prototyp, auf den sowohl "Schatten"A
alsB
auch "Schatten" Zugriff hättenObject.prototype
.x
,y
undmodify
und damit alle SchattenC
‚s Mitglieder. Was bringt es, C in den Prototyp einzufügen, wenn Sie es nicht verwenden? Es ist toter Code.quelle