aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/javascript/reference/operators/super/index.html
blob: 4f3b525185faa08a67341ff41bce86b7401b66df (plain)
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
---
title: super
slug: Web/JavaScript/Reference/Operators/super
tags:
  - ECMAScript 2015
  - JavaScript
  - Классы
translation_of: Web/JavaScript/Reference/Operators/super
---
<div>{{jsSidebar("Operators")}}</div>

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

<p>Выражения: <code>super.prop</code> и <code>super[expr]</code> - действительны в любом методе определения в обоих классах и в литералах объекта.</p>

<h2 id="Синтаксис">Синтаксис</h2>

<pre class="syntaxbox notranslate">super([arguments]); // вызов родительского конструктора.
super.functionOnParent([arguments]);
</pre>

<h2 id="Описание">Описание</h2>

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

<h2 id="Пример">Пример</h2>

<h3 id="Использование_super_в_классах">Использование super в классах</h3>

<p>Этот фрагмент кода взят из <a href="https://github.com/GoogleChrome/samples/blob/gh-pages/classes-es6/index.html">classes sample</a> (<a href="https://googlechrome.github.io/samples/classes-es6/index.html">live demo</a>). В этом примере <code>super()</code> вызывается , чтобы предотвратить использования одинакового для классов <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">Rectangle</span></font> and <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">Square</span></font> определения тела конструктора.</p>

<pre class="brush: js notranslate">class Polygon {
  constructor(height, width) {
    this.name = 'Polygon';
    this.height = height;
    this.width = width;
  }
  sayName() {
    console.log('Hi, I am a ', this.name + '.');
  }
}

class Square extends Polygon {
  constructor(length) {
    this.height; // ReferenceError, super должен быть вызыван первым!

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

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

  get area() {
    return this.height * this.width;
  }

  set area(value) {
    this.area = value;
  }
}</pre>

<h3 id="Супер-вызовы_статических_методов">Супер-вызовы статических методов</h3>

<p>Вы так же можете вызывать super на <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes/static">статических</a> методах.</p>

<pre class="notranslate">class Rectangle {
  constructor() {}
  static logNbSides() {
    return 'У меня 4 стороны,';
  }
}

class Square extends Rectangle {
  constructor() {}
  static logDescription() {
    return super.logNbSides() + ' которые все равны';
  }
}
Square.logDescription(); // 'У меня 4 стороны, которые все равны'</pre>

<h3 id="Удаление_свойств_super_вызывает_ошибку">Удаление свойств super вызывает ошибку</h3>

<p>Вы не можете использовать <a href="/en-US/docs/Web/JavaScript/Reference/Operators/delete">delete operator</a> и <code>super.prop</code> или <code>super[expr]</code> при удалении родительского класса он выдаст:{{jsxref("ReferenceError")}}.</p>

<pre class="brush: js notranslate">class Base {
  constructor() {}
  foo() {}
}
class Derived extends Base {
  constructor() {}
  delete() {
    delete super.foo; // это плохо
  }
}

new Derived().delete(); // ReferenceError: invalid delete involving 'super'. </pre>

<h3 id="super.prop_не_может_переопределять_свойства_защищённые_от_записи"><code>super.prop</code> не может переопределять свойства, защищённые от записи</h3>

<p>При определении незаписываемых свойств с помощью, например, {{jsxref("Object.defineProperty")}}, <code>super</code> не может перезаписать значение свойства.</p>

<pre class="notranslate">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</pre>

<h3 id="Использование_super.prop_в_объектных_литералах">Использование <code>super.prop</code> в объектных литералах</h3>

<p>Super также можно использовать в <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer">объекте инициализатора / литерала</a>. В этом примере, два объекта определяют метод. Во втором объекте, <code>super</code> вызывает первый метод объекта. Это работает с помощью {{jsxref("Object.setPrototypeOf()")}}, с которой мы можем установить прототип для <code>obj2</code> в <code>obj1</code>, так что <code>super</code> может найти <code>method1</code> в <code>obj1</code>.</p>

<pre class="brush: js notranslate">var obj1 = {
  method1() {
    console.log("method 1");
  }
}

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

Object.setPrototypeOf(obj2, obj1);
obj2.method2(); // logs "method 1"
</pre>

<h2 id="Характеристики">Характеристики</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Характеристики</th>
   <th scope="col">Статус</th>
   <th scope="col">Комментарий</th>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-super-keyword', 'super')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td>Initial definition.</td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-super-keyword', 'super')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="Совместимость_в_браузерах">Совместимость в браузерах</h2>

<p>{{Compat("javascript.operators.super")}}</p>

<div id="compat-mobile"></div>

<h2 id="Gecko_specific_notes">Gecko specific notes</h2>

<ul>
 <li><code>super()</code> does not yet work as expected for built-in prototypes.</li>
</ul>

<h2 id="Смотрите_также">Смотрите также</h2>

<ul>
 <li><a href="/en-US/docs/Web/JavaScript/Reference/Classes">Классы</a></li>
</ul>