|
2 | 2 |
|
3 | 3 | В программировании мы часто хотим взять что-то и расширить. |
4 | 4 |
|
5 | | -Например, у нас есть объект `user` со своими свойствами и методами, и мы хотим создать объекты `admin` и `guest` как его слегка измененные варианты. Мы хотели бы повторно использовать то, что есть у объекта `user`, не копировать/переопределять его методы, но просто создать новый объект поверх него. |
| 5 | +Например, у нас есть объект `user` со своими свойствами и методами, и мы хотим создать объекты `admin` и `guest` как его слегка измененные варианты. Мы хотели бы повторно использовать то, что есть у объекта `user`, не копировать/переопределять его методы, а просто создать новый объект на его основе. |
6 | 6 |
|
7 | | -*Прототипное наследование* — это особенность языка, которая помогает в этом. |
| 7 | +*Прототипное наследование* — это возможность языка, которая помогает в этом. |
8 | 8 |
|
9 | 9 | ## [[Prototype]] |
10 | 10 |
|
11 | | -В JavaScript объекты имеют специальное скрытое свойство `[[Prototype]]` (как указано в спецификации), которое либо равно `null`, либо ссылается на другой объект. Этот объект называется "прототип": |
| 11 | +В JavaScript объекты имеют специальное скрытое свойство `[[Prototype]]` (так оно названо в спецификации), которое либо равно `null`, либо ссылается на другой объект. Этот объект называется "прототип": |
12 | 12 |
|
13 | 13 |  |
14 | 14 |
|
15 | | -Этот `[[Prototype]]` имеет "магическое" значение. Когда мы хотим прочитать свойство из `объекта`, а оно отсутствует, JavaScript автоматически берет его из прототипа. В программировании такой механизм называется "прототипным наследованием". Многие интересные возможности языка и техники программирования основываются на нем. |
| 15 | +Этот `[[Prototype]]` дает нам немного "магии". Когда мы хотим прочитать свойство из `объекта`, а оно отсутствует, JavaScript автоматически берет его из прототипа. В программировании такой механизм называется "прототипным наследованием". Многие интересные возможности языка и техники программирования основываются на нем. |
16 | 16 |
|
17 | 17 | Свойство `[[Prototype]]` является внутренним и скрытым, но есть много способов задать его самостоятельно. |
18 | 18 |
|
@@ -136,7 +136,7 @@ alert(longEar.jumps); // true (для rabbit) |
136 | 136 | 1. Ссылки не могут идти по кругу. JavaScript выдаст ошибку, если мы попытаемся назначить `__proto__` по кругу. |
137 | 137 | 2. Значение `__proto__` может быть как объектом, так и `null`, другие типы (например, примитивы) игнорируются. |
138 | 138 |
|
139 | | -Это скорее всего очевидно, но все же: может быть только один `[[Prototype]]`. Объект не может наследоваться от двух других. |
| 139 | +Это вполне очевидно, но все же: может быть только один `[[Prototype]]`. Объект не может наследоваться от двух других. |
140 | 140 |
|
141 | 141 | ## Запись не использует прототип |
142 | 142 |
|
@@ -171,7 +171,7 @@ rabbit.walk(); // Rabbit! Bounce-bounce! |
171 | 171 |
|
172 | 172 |  |
173 | 173 |
|
174 | | -Это справедливо только для свойств данных, а не для методов доступа. Если свойство является геттером/сеттером, то оно ведет себя как функция: геттеры/сеттеры ищутся в прототипе. |
| 174 | +Это справедливо только для свойств данных, но не для аксессоров. Если свойство является геттером/сеттером, то оно ведет себя как функция: геттеры/сеттеры ищутся в прототипе. |
175 | 175 |
|
176 | 176 | По этой причине `admin.fullName` работает корректно в приведенном ниже коде: |
177 | 177 |
|
@@ -200,11 +200,11 @@ alert(admin.fullName); // John Smith (*) |
200 | 200 | admin.fullName = "Alice Cooper"; // (**) |
201 | 201 | ``` |
202 | 202 |
|
203 | | -Здесь в строке `(*)` свойство `admin.fullName` имеет геттер в прототипе `user`, поэтому вызывается он. В строке `(**)` свойство так же имеет сеттер в прототипе, который и будет вызван. |
| 203 | +Здесь в строке `(*)` свойство `admin.fullName` имеет геттер в прототипе `user`, поэтому вызывается он. В строке `(**)` свойство также имеет сеттер в прототипе, который и будет вызван. |
204 | 204 |
|
205 | 205 | ## Значение "this" |
206 | 206 |
|
207 | | -В приведенном выше примере может возникнуть интересный вопрос: каково значение `this` внутри `set fullName(value)`? Где записаны свойства `this.name` и `this.surname`: в `user` или `admin`? |
| 207 | +В приведенном выше примере может возникнуть интересный вопрос: каково значение `this` внутри `set fullName(value)`? Куда записаны свойства `this.name` и `this.surname`: в `user` или `admin`? |
208 | 208 |
|
209 | 209 | Ответ прост: прототипы никак не влияют на `this`. |
210 | 210 |
|
@@ -256,5 +256,5 @@ alert(animal.isSleeping); // undefined (нет такого свойства в |
256 | 256 | - В JavaScript все объекты имеют скрытое свойство `[[Prototype]]`, которое является либо другим объектом, либо `null`. |
257 | 257 | - Мы можем использовать `obj.__ proto__` для доступа к нему (исторически обусловленный геттер/сеттер, есть другие способы, которые скоро будут рассмотрены). |
258 | 258 | - Объект, на который ссылается `[[Prototype]]`, называется "прототипом". |
259 | | -- Если мы хотим прочитать свойство `obj` или вызвать метод, а оно не существует, тогда JavaScript попытается найти его в прототипе. Операции записи/удаления работают непосредственно с объектом, они не используют прототип (если свойство фактически не является сеттером). |
260 | | -- Если мы вызываем `obj.method()`, а метод взят из прототипа, он все равно ссылается на `obj`. Таким образом, методы всегда работают с текущим объектом, даже если они наследуются. |
| 259 | +- Если мы хотим прочитать свойство `obj` или вызвать метод, которого не существует, тогда JavaScript попытается найти его в прототипе. Операции записи/удаления работают непосредственно с объектом, они не используют прототип (если свойство фактически не является сеттером). |
| 260 | +- Если мы вызываем `obj.method()`, а метод взят из прототипа, то `this` все равно ссылается на `obj`. Таким образом, методы всегда работают с текущим объектом, даже если они наследуются. |
0 commit comments