Skip to content

Commit 549af79

Browse files
committed
fixes
1 parent 413e552 commit 549af79

2 files changed

Lines changed: 143 additions & 43 deletions

File tree

1-js/10-es-modern/6-es-object/article.md

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -76,26 +76,23 @@ alert( user["мой зелёный крокодил"] ); // Вася
7676
<li>`Object.getPrototypeOf(obj)`</li>
7777
</ul>
7878

79-
В современной JavaScript также добавился сеттер:
79+
В ES-2015 также добавился сеттер:
8080
<ul>
8181
<li>`Object.setPrototypeOf(obj, newProto)`</li>
8282
</ul>
8383

8484
...А также "узаконено" свойство `__proto__`, которое даёт прямой доступ к прототипу. Его, в качестве "нестандартного", но удобного способа работы с прототипом реализовали почти все браузеры (кроме IE10-), так что было принято решение добавить его в стандарт.
8585

86-
По стандарту оно реализовано через геттеры-сеттеры `Object.getPrototypeOf/setPrototypeOf`.
87-
88-
8986
## Object.assign
9087

88+
Функция `Object.assign` получает список объектов и копирует в первый `target` свойства из остальных.
89+
9190
Синтаксис:
9291
```js
9392
Object.assign(target, src1, src2...)
9493
```
9594

96-
Функция `Object.assign` получает список объектов и копирует в первый `target` свойства из остальных.
97-
98-
Последующие свойства перезаписывают предыдущие.
95+
При этом последующие свойства перезаписывают предыдущие.
9996

10097
Например:
10198

@@ -109,14 +106,31 @@ let admin = { isAdmin: true };
109106

110107
Object.assign(user, visitor, admin);
111108

109+
// user <- visitor <- admin
112110
alert( JSON.stringify(user) ); // user: Вася, visits: true, isAdmin: true
113111
```
114112

113+
Его также можно использовать для 1-уровневого клонирования объекта:
114+
115+
```js
116+
'use strict';
117+
118+
let user = { name: "Вася", isAdmin: false };
119+
120+
*!*
121+
// clone = пустой объект + все свойства user
122+
let clone = Object.assign({}, user);
123+
*/!*
124+
```
125+
126+
115127
## Object.is(value1, value2)
116128

117-
Возвращает `true`, если `value1 === value2`, иначе `false`.
129+
Новая функция для проверки равенства значений.
130+
131+
Возвращает `true`, если значения `value1` и `value2` равны, иначе `false`.
118132

119-
Есть, однако, два отличия от обычного `===`, а именно:
133+
Она похожа на обычное строгое равенство `===`, но есть отличия:
120134

121135
```js
122136
//+ run
@@ -130,20 +144,20 @@ alert( Object.is(NaN, NaN) ); // true
130144
alert( NaN === NaN ); // false
131145
```
132146

133-
При сравнении объектов через `Object.is` успользуется алгоритм [SameValue](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-samevalue), который неявно применяется во многих других местах современного стандарта.
147+
Отличия эти в большинстве ситуаций некритичны, так что непохоже, чтобы эта функция вытеснила обычную проверку `===`. Что интересно -- этот алгоритм сравнения, который называется [SameValue](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-samevalue), применяется во внутренних реализациях различных методов современного стандарта.
134148

135149

136150
## Методы объекта
137151

138152
Долгое время в JavaScript термин "метод объекта" был просто альтернативным названием для свойства-функции.
139153

140-
Теперь это уже не так, добавлены именно "методы объекта". Они, по сути, являются "свойствами-функциями, привязанными к объекту".
154+
Теперь это уже не так, добавлены именно "методы объекта", которые, по сути, являются свойствами-функциями, привязанными к объекту.
141155

142156
Их особенности:
143157

144158
<ol>
145-
<li>Более короткий синтаксис.</li>
146-
<li>Наличие в методах специального внутреннего свойства `[[HomeObject]]` ("домашний объект"), ссылающегося на объект, которому метод принадлежит. Мы посмотрим его использование чуть дальше, в разделе про `super`.</li>
159+
<li>Более короткий синтаксис объявления.</li>
160+
<li>Наличие в методах специального внутреннего свойства `[[HomeObject]]` ("домашний объект"), ссылающегося на объект, которому метод принадлежит. Мы посмотрим его использование чуть дальше.</li>
147161
</ol>
148162

149163
Для объявления метода вместо записи `"prop: function() {…}"` нужно написать просто `"prop() { … }"`.
@@ -158,7 +172,7 @@ let name = "Вася";
158172
let user = {
159173
name,
160174
*!*
161-
/* вместо sayHi: function() { */
175+
// вместо "sayHi: function() {" пишем "sayHi() {"
162176
sayHi() {
163177
alert(this.name);
164178
}
@@ -168,7 +182,7 @@ let user = {
168182
user.sayHi(); // Вася
169183
```
170184

171-
Как видно, создание такого метода -- чуть короче, а обращение -- не отличается от обычной функции.
185+
Как видно, для создания метода нужно писать меньше букв. Что же касается вызова -- он ничем не отличается от обычной функции. На данном этапе можно считать, что "метод" -- это просто сокращённый синтаксис для свойства-функции. Дополнительные возможности, которые даёт такое объявление, мы рассмотрим позже.
172186

173187
Также методами станут объявления геттеров `get prop()` и сеттеров `set prop()`:
174188

@@ -207,11 +221,17 @@ let user = {
207221
alert( user.getFirstName() ); // Вася
208222
```
209223

224+
Итак, мы рассмотрели синтаксические улучшения. Если коротко, то не надо писать слово "function". Теперь перейдём к другим отличиям.
225+
210226
## super
211227

228+
В ES-2015 появилось новое ключевое слово `super`. Оно предназначено только для использования в методах объекта.
229+
212230
Вызов `super.parentProperty` позволяет из метода объекта получить свойство его прототипа.
213231

214-
Например, в коде ниже `rabbit` наследует от `animal`. Вызов `super.walk` из метода объекта `rabbit` обращается к `animal.walk`:
232+
Например, в коде ниже `rabbit` наследует от `animal`.
233+
234+
Вызов `super.walk()` из метода объекта `rabbit` обращается к `animal.walk()`:
215235

216236
```js
217237
//+ run
@@ -236,9 +256,11 @@ let rabbit = {
236256
rabbit.walk();
237257
```
238258

259+
Как правило, это используется в [классах](/class), которые мы рассмотрим в следующем разделе, но важно понимать, что "классы" здесь на самом деле не при чём. Свойство `super` работает через прототип, на уровне методов объекта.
260+
239261
При обращении через `super` используется `[[HomeObject]]` текущего метода, и от него берётся `__proto__`. Поэтому `super` работает только внутри методов.
240262

241-
Например, если переписать этот код, оформив `rabbit.walk` как обычное свойство-функцию, то будет ошибка:
263+
В частности, если переписать этот код, оформив `rabbit.walk` как обычное свойство-функцию, то будет ошибка:
242264

243265
```js
244266
//+ run
@@ -253,7 +275,7 @@ let animal = {
253275
let rabbit = {
254276
__proto__: animal,
255277
*!*
256-
walk: function() {
278+
walk: function() { // Надо: walk() {
257279
super.walk(); // Будет ошибка!
258280
}
259281
*/!*
@@ -289,9 +311,11 @@ let rabbit = {
289311
rabbit.walk();
290312
```
291313

314+
Ранее мы говорили о том, что у функций-стрелок нет своего `this`, `arguments`: они используют те, которые во внешней функции. Теперь к этому списку добавился ещё и `super`.
315+
292316
[smart header="Свойство `[[HomeObject]]` -- не изменяемое"]
293317

294-
При создании метода -- он привязан к своему объекту навсегда. Технически можно даже скопировать его и запустить независимо:
318+
При создании метода -- он привязан к своему объекту навсегда. Технически можно даже скопировать его и запустить отдельно, и `super` продолжит работать:
295319

296320
```js
297321
//+ run
@@ -310,14 +334,14 @@ let rabbit = {
310334

311335
let walk = rabbit.walk; // скопируем метод в переменную
312336
*!*
313-
walk();
337+
walk(); // вызовет animal.walk()
314338
// I'm walking
315339
*/!*
316340
```
317341

318342
В примере выше метод `walk()` запускается отдельно от объекта, но всё равно сохраняется через `super` доступ к его прототипу, благодаря `[[HomeObject]]`.
319343

320-
Это относится именно к `super`. Правила `this` для методов те же, что и для обычных функций. В примере выше при вызове `walk()` без объекта `this` будет `undefined`.
344+
Это -- скорее технический момент, так как методы объекта, всё же, предназначены для вызова в контексте этого объекта. В частности, правила для `this` в методах -- те же, что и для обычных функций. В примере выше при вызове `walk()` без объекта `this` будет `undefined`.
321345
[/smart]
322346

323347
## Итого

0 commit comments

Comments
 (0)