Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten.Erfahre mehr über dieses Experiment.
super
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since März 2016.
Dassuper Schlüsselwort wird verwendet, um auf Eigenschaften eines Objekt-Literals oder des [[Prototyps]] einer Klasse zuzugreifen oder um den Konstruktor einer Oberklasse aufzurufen.
Die Ausdrückesuper.prop undsuper[expr] sind in jederMethodendefinition sowohl inKlassen als auch inObjekt-Literals gültig. Der Ausdrucksuper(...args) ist in Klassenkonstruktoren gültig.
In diesem Artikel
Probieren Sie es aus
class Foo { constructor(name) { this.name = name; } getNameSeparator() { return "-"; }}class FooBar extends Foo { constructor(name, index) { super(name); this.index = index; } // Does not get called getNameSeparator() { return "/"; } getFullName() { return this.name + super.getNameSeparator() + this.index; }}const firstFooBar = new FooBar("foo", 1);console.log(firstFooBar.name);// Expected output: "foo"console.log(firstFooBar.getFullName());// Expected output: "foo-1"Syntax
super()super(arg1)super(arg1, arg2)super(arg1, arg2, /* …, */ argN)super.propertyOnParentsuper[expression]Beschreibung
Das Schlüsselwortsuper kann auf zwei Arten verwendet werden: als „Funktionsaufruf“ (super(...args)) oder als „Eigenschaftszugriff“ (super.prop undsuper[expr]).
Hinweis:super ist ein Schlüsselwort und diese sind spezielle syntaktische Konstrukte.super ist keine Variable, die auf das Prototyp-Objekt zeigt. Der Versuch,super selbst zu lesen, führt zu einemSyntaxError.
const child = { myParent() { console.log(super); // SyntaxError: 'super' keyword unexpected here },};ImKonstruktor-Körper einer abgeleiteten Klasse (mitextends) kann das Schlüsselwortsuper als „Funktionsaufruf“ (super(...args)) erscheinen, der vor der Verwendung des Schlüsselwortsthis und vor der Rückgabe des Konstruktors aufgerufen werden muss. Es ruft den Konstruktor der Elternklasse auf und bindet die öffentlichen Felder der Elternklasse, wonach der Konstruktor der abgeleiteten Klassethis weiter zugreifen und modifizieren kann.
Die Form „Eigenschaftszugriff“ kann verwendet werden, um Methoden und Eigenschaften des [[Prototyps]] eines Objekt-Literals oder einer Klasse zuzugreifen. Innerhalb des Korpus einer Klasse kann die Referenz vonsuper entweder der Konstruktor der Oberklasse selbst oder dasprototype des Konstruktors sein, je nachdem ob der Ausführungskontext die Erstellung einer Instanz oder die Initialisierung der Klasse ist. Siehe den Abschnitt Beispiele für weitere Details.
Beachten Sie, dass die Referenz vonsuper von der Klasse oder dem Objekt-Literal bestimmt wird, in demsuper deklariert wurde, nicht vom Objekt, auf dem die Methode aufgerufen wird. Daher ändert das Entbinden oder Neu-Binden einer Methode nicht die Referenz vonsuper darin (obwohl sie die Referenz vonthis ändern). Sie könnensuper als eine Variable im Scope der Klasse oder des Objekt-Literals sehen, über die die Methoden einen Closure erstellen. (Aber beachten Sie auch, dass es tatsächlich keine Variable ist, wie oben erklärt.)
Beim Setzen von Eigenschaften übersuper wird die Eigenschaft stattdessen aufthis gesetzt.
Beispiele
>Verwendung von super in Klassen
Dieses Codebeispiel stammt aus demKlassenbeispiel (Live-Demo). Hier wirdsuper() aufgerufen, um die Konstruktor-Teile zu vermeiden, die zwischenRectangle undSquare gemeinsam sind.
class Rectangle { constructor(height, width) { this.name = "Rectangle"; this.height = height; this.width = width; } sayName() { console.log(`Hi, I am a ${this.name}.`); } get area() { return this.height * this.width; } set area(value) { this._area = value; }}class Square extends Rectangle { constructor(length) { // Here, it calls the parent class's constructor with lengths // provided for the Rectangle's width and height super(length, length); // Note: In derived classes, super() must be called before you // can use 'this'. Moving this to the top causes a ReferenceError. this.name = "Square"; }}Super-Aufruf von statischen Methoden
Sie können auchsuper aufstatische Methoden aufrufen.
class Rectangle { static logNbSides() { return "I have 4 sides"; }}class Square extends Rectangle { static logDescription() { return `${super.logNbSides()} which are all equal`; }}Square.logDescription(); // 'I have 4 sides which are all equal'Zugriff auf super in Deklarationen von Klassenfeldern
super kann auch während der Feldinitialisierung der Klasse zugegriffen werden. Die Referenz vonsuper hängt davon ab, ob das aktuelle Feld ein Instanzfeld oder ein statisches Feld ist.
class Base { static baseStaticField = 90; baseMethod() { return 10; }}class Extended extends Base { extendedField = super.baseMethod(); // 10 static extendedStaticField = super.baseStaticField; // 90}Beachten Sie, dass Instanzfelder auf der Instanz anstelle desprototype des Konstruktors gesetzt werden, sodass Siesuper nicht verwenden können, um auf das Instanzfeld einer Oberklasse zuzugreifen.
class Base { baseField = 10;}class Extended extends Base { extendedField = super.baseField; // undefined}Hier istextendedFieldundefined anstelle von 10, weilbaseField als eine Fremdeigenschaft derBase Instanz definiert ist, anstelle vonBase.prototype.super schaut in diesem Kontext nur Eigenschaften aufBase.prototype nach, weil das der [[Prototyp]] vonExtended.prototype ist.
Das Löschen von super-Eigenschaften führt zu einem Fehler
Sie können dendelete Operator undsuper.prop odersuper[expr] nicht verwenden, um eine Eigenschaft einer Elternklasse zu löschen — es führt zu einemReferenceError.
class Base { foo() {}}class Derived extends Base { delete() { delete super.foo; // this is bad }}new Derived().delete(); // ReferenceError: invalid delete involving 'super'.Verwendung von super.prop in Objekt-Literals
Super kann auch in derObjekt-Initialisierer Notation verwendet werden. In diesem Beispiel definieren zwei Objekte eine Methode. Im zweiten Objekt ruftsuper die Methode des ersten Objekts auf. Dies funktioniert mit Hilfe vonObject.setPrototypeOf(), mit dem wir in der Lage sind, den Prototyp vonobj2 aufobj1 zu setzen, sodasssuper in der Lage ist,method1 aufobj1 zu finden.
const obj1 = { method1() { console.log("method 1"); },};const obj2 = { method2() { super.method1(); },};Object.setPrototypeOf(obj2, obj1);obj2.method2(); // Logs "method 1"Methoden, die super.prop lesen, verhalten sich nicht anders, wenn sie an andere Objekte gebunden sind
Der Zugriff aufsuper.x verhält sich wieReflect.get(Object.getPrototypeOf(objectLiteral), "x", this), was bedeutet, dass die Eigenschaft immer auf dem Prototyp des Objekt-Literals / der Klassendeklaration gesucht wird, und das Entbinden und Neu-Binden einer Methode die Referenz vonsuper nicht verändert.
class Base { baseGetX() { return 1; }}class Extended extends Base { getX() { return super.baseGetX(); }}const e = new Extended();console.log(e.getX()); // 1const { getX } = e;console.log(getX()); // 1Dasselbe passiert in Objekt-Literals.
const parent1 = { prop: 1 };const parent2 = { prop: 2 };const child = { myParent() { console.log(super.prop); },};Object.setPrototypeOf(child, parent1);child.myParent(); // Logs "1"const myParent = child.myParent;myParent(); // Still logs "1"const anotherChild = { __proto__: parent2, myParent };anotherChild.myParent(); // Still logs "1"Nur das Zurücksetzen der gesamten Vererbungskette wird die Referenz vonsuper ändern.
class Base { baseGetX() { return 1; } static staticBaseGetX() { return 3; }}class AnotherBase { baseGetX() { return 2; } static staticBaseGetX() { return 4; }}class Extended extends Base { getX() { return super.baseGetX(); } static staticGetX() { return super.staticBaseGetX(); }}const e = new Extended();// Reset instance inheritanceObject.setPrototypeOf(Extended.prototype, AnotherBase.prototype);console.log(e.getX()); // Logs "2" instead of "1", because the prototype chain has changedconsole.log(Extended.staticGetX()); // Still logs "3", because we haven't modified the static part yet// Reset static inheritanceObject.setPrototypeOf(Extended, AnotherBase);console.log(Extended.staticGetX()); // Now logs "4"Methodenaufrufe von super
Beim Aufruf vonsuper.prop als Funktion ist derthis Wert innerhalb derprop Funktion das aktuellethis, nicht das Objekt, auf dassuper zeigt. Zum Beispiel protokolliert der Aufruf vonsuper.getName()"Extended", obwohl der Code so aussieht, als wäre er äquivalent zuBase.getName().
class Base { static getName() { console.log(this.name); }}class Extended extends Base { static getName() { super.getName(); }}Extended.getName(); // Logs "Extended"Das ist besonders wichtig, wenn Sie mitstatischen privaten Elementen interagieren.
Das Setzen von super.prop setzt die Eigenschaft stattdessen auf this
Das Setzen von Eigenschaften vonsuper, wiesuper.x = 1, verhält sich wieReflect.set(Object.getPrototypeOf(objectLiteral), "x", 1, this). Dies ist einer der Fälle, in denen das Verständnis vonsuper als einfache "Referenz des Prototyp-Objekts" nicht ausreicht, da es tatsächlich die Eigenschaft aufthis setzt.
class A {}class B extends A { setX() { super.x = 1; }}const b = new B();b.setX();console.log(b); // B { x: 1 }console.log(Object.hasOwn(b, "x")); // truesuper.x = 1 wird den Eigenschafts-Deskriptor vonx aufA.prototype suchen (und die dort definierten Setter aufrufen), aber derthis Wert wird aufthis gesetzt, was in diesem Kontextb ist. Sie könnenReflect.set lesen, um mehr Details zu dem Fall zu erfahren, in dem sichtarget undreceiver unterscheiden.
Das bedeutet, dass während Methoden, diesuper.proplesen, in der Regel nicht anfällig für Änderungen imthis Kontext sind, diejenigen, diesuper.propsetzen, es sind.
/* Reusing same declarations as above */const b2 = new B();b2.setX.call(null); // TypeError: Cannot assign to read only property 'x' of object 'null'Jedoch konsultiertsuper.x = 1 dennoch den Eigenschafts-Deskriptor des Prototyp-Objekts, was bedeutet, dass Sie nicht in der Lage sind, nicht schreibbare Eigenschaften neu zu schreiben, und Setter werden aufgerufen.
class X { constructor() { // Create a non-writable property Object.defineProperty(this, "prop", { configurable: true, writable: false, value: 1, }); }}class Y extends X { constructor() { super(); } foo() { super.prop = 2; // Cannot overwrite the value. }}const y = new Y();y.foo(); // TypeError: "prop" is read-onlyconsole.log(y.prop); // 1Spezifikationen
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-super-keyword> |