super
=====

Ключевое слово **super** используется для вызова функций, принадлежащих родителю объекта.

Выражения `super.prop` и `super[expr]` действительны в любом определении метода в классах и в литералах объекта.

Синтаксис
---------


```js
super([arguments]); // вызов родительского конструктора.
super.functionOnParent([arguments]);
```

Описание
--------

В конструкторе ключевое слово `super()` используется как функция, вызывающая родительский конструктор. Её необходимо вызвать до первого обращения к ключевому слову `this` в теле конструктора. Ключевое слово `super` также может быть использовано для вызова функций родительского объекта.

Пример
------

### Использование super в классах

Этот фрагмент кода взят из classes sample (демонстрация). В этом примере `super()` вызывается, чтобы не повторять части конструктора, одинаковые для классов `Rectangle` и `Square`.


```js
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) {
    this.height; // ReferenceError, super должен быть вызван первым!

    // Здесь вызывается конструктор родительского класса с длинами,
    // указанными для ширины и высоты класса Rectangle
    super(length, length);

    // Примечание: в производных классах super() необходимо вызывать, прежде чем
    // использовать 'this'. Если этого не сделать, произойдет ошибка ReferenceError.
    this.name = "Square";
  }
}
```

### Вызов статических методов через super

Вы также можете вызывать super для статических методов.


```js
class Rectangle {
  static logNbSides() {
    return "У меня 4 стороны";
  }
}

class Square extends Rectangle {
  static logDescription() {
    return super.logNbSides() + ", равные между собой";
  }
}
Square.logDescription(); // 'У меня 4 стороны, равные между собой'
```

### Удаление свойств через super вызывает ошибку

Вы не можете использовать оператор delete и `super.prop` или `super[expr]` для удаления свойств родительского класса, он выдаст: `ReferenceError`.


```js
class Base {
  constructor() {}
  foo() {}
}
class Derived extends Base {
  constructor() {}
  delete() {
    delete super.foo; // это плохо
  }
}

new Derived().delete(); // ReferenceError: invalid delete involving 'super'.
```

### `super.prop` не может переопределять свойства, защищённые от записи

При определении незаписываемых свойств с помощью, например, `Object.defineProperty`, `super` не может перезаписать значение свойства.


```js
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`.


```js
var obj1 = {
  method1() {
    console.log("method 1");
  },
};

var obj2 = {
  method2() {
    super.method1();
  },
};

Object.setPrototypeOf(obj2, obj1);
obj2.method2(); // выведет "method 1"
```

Спецификации
------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-super-keyword |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

* Классы