Ключове слово super використовується для доступу до функцій на батьківському об'єкті та виклику цих функцій.
Вирази super.prop
та super[expr]
є коректними у будь-якому визначенні методу як у класах, так і у об'єктних літералах.
Синтаксис
super([arguments]); // викликає батьківський конструктор. super.functionOnParent([arguments]);
Опис
При застосуванні у конструкторі ключове слово super
використовується окремо та має викликатись до ключового слова this
. Ключове слово super
також може використовуватись у викликах функцій батьківського об'єкта.
Приклад
Використання super
у класах
Цей фрагмент коду взято з прикладу класів (демонстрація). Тут super()
викликається для запобігання дублюванню частин конструктора, які є спільними у Rectangle
(прямокутник) та Square
(квадрат).
class Rectangle {
constructor(height, width) {
this.name = 'Прямокутник';
this.height = height;
this.width = width;
}
sayName() {
console.log('Привіт, я ', this.name + '.');
}
get area() {
return this.height * this.width;
}
set area(value) {
this._area = value;
}
}
class Square extends Rectangle {
constructor(length) {
this.height; // ReferenceError, спочатку має викликатись super!
// Тут ми викликаємо конструктор батьківського класу з довжиною
// в якості ширини та довжини прямокутника
super(length, length);
// Заувага: У похідному класі super() має викликатись до 'this'.
// Не врахувавши це, ви отримаєте помилку посилання.
this.name = 'Квадрат';
}
}
Виклик статичних методів через super
Ви також можете викликати через super статичні методи.
class Rectangle {
constructor() {}
static logNbSides() {
return 'Я маю 4 сторони';
}
}
class Square extends Rectangle {
constructor() {}
static logDescription() {
return super.logNbSides() + ', і вони рівні';
}
}
Square.logDescription(); // 'Я маю 4 сторони, і вони рівні'
Видалення super-властивостей викине помилку
Ви не можете використовувати оператор delete та super.prop
або super[expr]
, щоб видалити властивість батьківського класу, це викине ReferenceError
.
class Base {
constructor() {}
foo() {}
}
class Derived extends Base {
constructor() {}
delete() {
delete super.foo; // це погано
}
}
new Derived().delete(); // ReferenceError: некоректний оператор delete з використанням 'super'.
super.prop
не може перезаписувати властивості, недоступні для запису
Коли властивості створені недоступними для запису, наприклад, за допомогою Object.defineProperty
, super
не може перезаписувати значення такої властивості.
class X {
constructor() {
Object.defineProperty(this, 'prop', {
configurable: true,
writable: false,
value: 1
});
}
}
class Y extends X {
constructor() {
super();
}
foo() {
super.prop = 2; // Не можна перезаписати значення.
}
}
var y = new Y();
y.foo(); // TypeError: "prop" доступна лише для читання
console.log(y.prop); // 1
Використання super.prop
у об'єктних літералах
Super також можна використовувати у нотації об'єктної ініціалізації / літералу. У цьому прикладі два об'єкти визначають метод. У другому об'єкті super
викликає метод першого об'єкта. Це працює завдяки методу Object.setPrototypeOf()
, який дає можливість встановити прототипом об'єкта obj2
об'єкт obj1
, таким чином, super
може знайти метод method1
на об'єкті obj1
.
var obj1 = {
method1() {
console.log('метод 1');
}
}
var obj2 = {
method2() {
super.method1();
}
}
Object.setPrototypeOf(obj2, obj1);
obj2.method2(); // виводить "метод 1"
Специфікації
Специфікація | Статус | Коментар |
---|---|---|
ECMAScript (ECMA-262) The definition of 'super' in that specification. |
Living Standard | |
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'super' in that specification. |
Standard | Початкове визначення. |
Сумісність з веб-переглядачами
BCD tables only load in the browser