You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/08-prototypes/01-prototype-inheritance/article.md
+40-40Lines changed: 40 additions & 40 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -31,7 +31,7 @@ rabbit.__proto__ = animal;
31
31
*/!*
32
32
```
33
33
34
-
```smart header="Свойство `__proto__` — историчеси геттер/сеттер для `[[Prototype]]`"
34
+
```smart header="Свойство `__proto__` — историчеси обусловленный геттер/сеттер для `[[Prototype]]`"
35
35
Обратите внимание, что `__proto__` — *не то же самое*, что `[[Prototype]]`. Это геттер/сеттер для него.
36
36
37
37
Он существует по историческим причинам, в современном языке его заменяют функции `Object.getPrototypeOf / Object.setPrototypeOf`, которые также получают/устанавливают прототип. Мы рассмотрим причины этого и эти функции позже.
@@ -72,7 +72,7 @@ alert( rabbit.jumps ); // true
72
72
73
73
Так что если у `animal` много полезных свойств и методов, то они автоматически становятся доступными у `rabbit`. Такие свойства называются "унаследованными".
74
74
75
-
If we have a method in`animal`, it can be called on`rabbit`:
75
+
Если у нас есть метод в`animal`, он может быть вызван на`rabbit`:
76
76
77
77
```js run
78
78
let animal = {
@@ -89,18 +89,17 @@ let rabbit = {
89
89
__proto__: animal
90
90
};
91
91
92
-
// walk is taken from the prototype
92
+
// walk взят из прототипа
93
93
*!*
94
94
rabbit.walk(); // Animal walk
95
95
*/!*
96
96
```
97
97
98
-
The method is automatically taken from the prototype, like this:
98
+
Метод автоматически берется из прототипа:
99
99
100
100

101
101
102
-
The prototype chain can be longer:
103
-
102
+
Цепочка прототипов может быть длиннее:
104
103
105
104
```js run
106
105
let animal = {
@@ -124,33 +123,33 @@ let longEar = {
124
123
*/!*
125
124
};
126
125
127
-
// walk is taken from the prototype chain
126
+
// walk взят из цепочки прототипов
128
127
longEar.walk(); // Animal walk
129
-
alert(longEar.jumps); // true (from rabbit)
128
+
alert(longEar.jumps); // true (для rabbit)
130
129
```
131
130
132
131

133
132
134
-
There are actually only two limitations:
133
+
На самом деле есть только два ограничения:
135
134
136
-
1.The references can't go in circles. JavaScript will throw an error if we try to assign `__proto__`in a circle.
137
-
2.The value of `__proto__`can be either an object or`null`, other types (like primitives) are ignored.
135
+
1.Ссылки не могут идти по кругу. JavaScript выдаст ошибку, если мы попытаемся назначить `__proto__`по кругу.
136
+
2.Значение `__proto__`может быть как объектом, так и`null`, другие типы (например, примитивы) игнорируются.
138
137
139
-
Also it may be obvious, but still: there can be only one `[[Prototype]]`. An object may not inherit from two others.
138
+
Также, это может быть очевидно, но все же: может быть только один `[[Prototype]]`. Объект не может наследоваться от двух других.
140
139
141
-
## Writing doesn't use prototype
140
+
## Запись не использует прототип
142
141
143
-
The prototype is only used for reading properties.
142
+
Прототип используется только для чтения свойств.
144
143
145
-
Write/delete operations work directly with the object.
144
+
Операции записи/удаления работают напрямую с объектом.
146
145
147
-
In the example below, we assign its own `walk` method to `rabbit`:
146
+
В приведенном ниже примере мы присваиваем `rabbit` собственный метод `walk`:
148
147
149
148
```js run
150
149
let animal = {
151
150
eats:true,
152
151
walk() {
153
-
/*this method won't be used by rabbit */
152
+
/*этот метод не будет использоваться в rabbit */
154
153
}
155
154
};
156
155
@@ -167,13 +166,13 @@ rabbit.walk = function() {
167
166
rabbit.walk(); // Rabbit! Bounce-bounce!
168
167
```
169
168
170
-
From now on, `rabbit.walk()` call finds the method immediately in the object and executes it, without using the prototype:
169
+
Теперь вызов rabbit.walk () находит метод непосредственно в объекте и выполняет его, не используя прототип:
171
170
172
171

173
172
174
-
That's for data properties only, not for accessors. If a property is a getter/setter, then it behaves like a function: getters/setters are looked up in the prototype.
173
+
Это справедливо только для свойств данных, а не для методов доступа. Если свойство является геттером/сеттером, то оно ведет себя как функция: геттеры/сеттеры ищутся в прототипе.
175
174
176
-
For that reason`admin.fullName`works correctly in the code below:
175
+
По этой причине`admin.fullName`работает корректно в приведенном ниже коде:
177
176
178
177
```js run
179
178
let user = {
@@ -196,27 +195,27 @@ let admin = {
196
195
197
196
alert(admin.fullName); // John Smith (*)
198
197
199
-
//setter triggers!
198
+
//срабатывает сеттер!
200
199
admin.fullName="Alice Cooper"; // (**)
201
200
```
202
201
203
-
Here in the line `(*)`the property `admin.fullName`has a getter in the prototype `user`, so it is called. And in the line `(**)`the property has a setter in the prototype, so it is called.
202
+
Здесь в строке `(*)`свойство `admin.fullName`имеет геттер в прототипе `user`, поэтому вызывается он. В строке `(**)`свойство так же имеет сеттер в прототипе, который и будет вызван.
204
203
205
-
## The value of "this"
204
+
## Значение "this"
206
205
207
-
An interesting question may arise in the example above: what's the value of `this`inside`set fullName(value)`? Where the properties`this.name`and`this.surname` are written: into`user`or`admin`?
206
+
В приведенном выше примере может возникнуть интересный вопрос: каково значение `this`внутри`set fullName(value)`? Где записаны свойства`this.name`и`this.surname`: в`user`или`admin`?
208
207
209
-
The answer is simple: `this` is not affected by prototypes at all.
208
+
Ответ прост: прототипы никак не влияют на `this`.
210
209
211
-
**No matter where the method is found: in an object or its prototype. In a method call, `this`is always the object before the dot.**
210
+
**Неважно, где находится метод: в объекте или его прототипе. В вызове метода, `this`— всегда объект перед точкой.**
212
211
213
-
So, the setter call `admin.fullName=`uses `admin` as `this`, not`user`.
212
+
Таким образом, вызов сеттера `admin.fullName=`в качестве `this` использует `admin`, а не`user`.
214
213
215
-
That is actually a super-important thing, because we may have a big object with many methods and inherit from it. Then inherited objects can run its methods, and they will modify the state of these objects, not the big one.
214
+
Это на самом деле очень важная вещь, потому что мы можем иметь большой объект со многими методами и наследовать его. Затем наследуемые объекты могут запускать его методы, и они будут изменять состояние этих объектов, а не большого.
216
215
217
-
For instance, here`animal`represents a "method storage", and`rabbit`makes use of it.
216
+
Например, здесь`animal`представляет собой "хранилище метода", и`rabbit`использует его.
218
217
219
-
The call `rabbit.sleep()`sets`this.isSleeping`on the`rabbit` object:
alert(animal.isSleeping); // undefined (no such property in the prototype)
242
+
alert(animal.isSleeping); // undefined (нет такого свойства в прототипе)
244
243
```
245
244
246
-
The resulting picture:
245
+
Картинка с результатом:
247
246
248
247

249
248
250
249
If we had other objects like `bird`, `snake` etc inheriting from `animal`, they would also gain access to methods of `animal`. But `this` in each method would be the corresponding object, evaluated at the call-time (before dot), not `animal`. So when we write data into `this`, it is stored into these objects.
250
+
Если бы у нас были другие объекты, такие как `bird`, `snake` и т.д., унаследованные от `animal`, они также получили бы доступ к методам `animal`. Но `this` в каждом методе будет соответствовать обьекту, на котором происходит вызов (до точки), а не `animal`. Поэтому, когда мы записываем данные в `this`, они сохраняются в этих объектах.
251
251
252
-
As a result, methods are shared, but the object state is not.
252
+
В результате методы являются общими, а состояние объекта — нет.
253
253
254
-
## Summary
254
+
## Итого
255
255
256
-
-In JavaScript, all objects have a hidden`[[Prototype]]` property that's either another object or`null`.
257
-
-We can use`obj.__proto__` to access it (a historical getter/setter, there are other ways, to be covered soon).
258
-
-The object referenced by`[[Prototype]]` is called a "prototype".
259
-
-If we want to read a property of `obj`or call a method, and it doesn't exist, then JavaScript tries to find it in the prototype. Write/delete operations work directly on the object, they don't use the prototype (unless the property is actually a setter).
260
-
-If we call`obj.method()`, and the `method` is taken from the prototype, `this` still references `obj`. So methods always work with the current object even if they are inherited.
256
+
-В JavaScript все объекты имеют скрытое свойство`[[Prototype]]`, которое является либо другим объектом, либо`null`.
257
+
-Мы можем использовать`obj .__ proto__` для доступа к нему (исторически обусловленный геттер/сеттер, есть другие способы, которые скоро будут рассмотрены).
258
+
-Объект, на который ссылается`[[Prototype]]`, называется "прототипом".
259
+
-Если мы хотим прочитать свойство `obj`или вызвать метод, а оно не существует, тогда JavaScript пытается найти его в прототипе. Операции записи/удаления работают непосредственно с объектом, они не используют прототип (если свойство фактически не является сеттером).
260
+
-Если мы вызываем`obj.method()`, а метод взят из прототипа, он все равно ссылается на `obj`. Таким образом, методы всегда работают с текущим объектом, даже если они наследуются.
0 commit comments