-
Notifications
You must be signed in to change notification settings - Fork 8k
/
index.md
160 lines (122 loc) · 5.8 KB
/
index.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
---
title: super
slug: Web/JavaScript/Reference/Operators/super
---
{{jsSidebar("Operators")}}
Ключевое слово **super** используется для вызова функций, принадлежащих родителю объекта.
Выражения `super.prop` и `super[expr]` действительны в любом [определении метода](/ru/docs/Web/JavaScript/Reference/Functions/Method_definitions) в [классах](/ru/docs/Web/JavaScript/Reference/Classes) и в [литералах объекта](/ru/docs/Web/JavaScript/Reference/Operators/Object_initializer).
## Синтаксис
```js
super([arguments]); // вызов родительского конструктора.
super.functionOnParent([arguments]);
```
## Описание
В конструкторе ключевое слово `super()` используется как функция, вызывающая родительский конструктор. Её необходимо вызвать до первого обращения к ключевому слову `this` в теле конструктора. Ключевое слово `super` также может быть использовано для вызова функций родительского объекта.
## Пример
### Использование super в классах
Этот фрагмент кода взят из [classes sample](https://github.com/GoogleChrome/samples/blob/gh-pages/classes-es6/index.html) ([демонстрация](https://googlechrome.github.io/samples/classes-es6/index.html)). В этом примере `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 для [статических](/ru/docs/Web/JavaScript/Reference/Classes/static) методов.
```js
class Rectangle {
static logNbSides() {
return "У меня 4 стороны";
}
}
class Square extends Rectangle {
static logDescription() {
return super.logNbSides() + ", равные между собой";
}
}
Square.logDescription(); // 'У меня 4 стороны, равные между собой'
```
### Удаление свойств через super вызывает ошибку
Вы не можете использовать [оператор delete](/ru/docs/Web/JavaScript/Reference/Operators/delete) и `super.prop` или `super[expr]` для удаления свойств родительского класса, он выдаст: {{jsxref("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` не может переопределять свойства, защищённые от записи
При определении незаписываемых свойств с помощью, например, {{jsxref("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 также можно использовать в [объекте инициализатора / литерала](/ru/docs/Web/JavaScript/Reference/Operators/Object_initializer). В этом примере метод определяют два объекта. Во втором объекте `super` вызывает метод первого объекта. Это работает благодаря {{jsxref("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"
```
## Спецификации
{{Specifications}}
## Совместимость с браузерами
{{Compat}}
## Смотрите также
- [Классы](/ru/docs/Web/JavaScript/Reference/Classes)