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/04-prototype-methods/2-dictionary-tostring/solution.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,6 +26,6 @@ for(let key in dictionary) {
26
26
alert(dictionary); // "apple,__proto__"
27
27
```
28
28
29
-
Когда мы создаем свойство с помощью дескриптора, все флаги по умолчанию имеют значение `false`. Таким образом, в коде выше `dictionary.toString` не перечисляемое свойство.
29
+
Когда мы создаём свойство с помощью дескриптора, все флаги по умолчанию имеют значение `false`. Таким образом, в коде выше `dictionary.toString` не перечисляемое свойство.
30
30
31
31
Смотрите главу [](info:property-descriptors) для ознакомления.
Copy file name to clipboardExpand all lines: 1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/task.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ importance: 5
6
6
7
7
Имеется объект `dictionary`, созданный с помощью `Object.create(null)` для хранения любых пар `ключ/значение`.
8
8
9
-
Добавьте ему метод `dictionary.toString()`, который должен возвращать список ключей разделенных запятой. Ваш `toString` не должен выводиться при итерации объекта с помощью цикла `for..in`.
9
+
Добавьте ему метод `dictionary.toString()`, который должен возвращать список ключей разделённых запятой. Ваш `toString` не должен выводиться при итерации объекта с помощью цикла `for..in`.
Copy file name to clipboardExpand all lines: 1-js/08-prototypes/04-prototype-methods/article.md
+18-18Lines changed: 18 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@
7
7
8
8
Современные методы это:
9
9
10
-
-[Object.create(proto[, descriptors])](mdn:js/Object/create) -- создает пустой объект со свойством `[[Prototype]]`, указанным как `proto`, и необязательными дескрипторами свойств.
10
+
-[Object.create(proto[, descriptors])](mdn:js/Object/create) -- создаёт пустой объект со свойством `[[Prototype]]`, указанным как `proto`, и необязательными дескрипторами свойств.
11
11
-[Object.getPrototypeOf(obj)](mdn:js/Object/getPrototypeOf) -- возвращает свойство `[[Prototype]]` объекта `obj`.
12
12
-[Object.setPrototypeOf(obj, proto)](mdn:js/Object/setPrototypeOf) -- устанавливает свойство `[[Prototype]]` объекта `obj` как `proto`.
13
13
@@ -20,7 +20,7 @@ let animal = {
20
20
eats:true
21
21
};
22
22
23
-
//создаем новый объект с прототипом animal
23
+
//создаём новый объект с прототипом animal
24
24
*!*
25
25
let rabbit =Object.create(animal);
26
26
*/!*
@@ -60,7 +60,7 @@ alert(rabbit.jumps); // true
60
60
let clone =Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
61
61
```
62
62
63
-
Такой вызов создает точную копию объекта `obj`, включая все свойства: перечисляемые и не перечисляемые, свойства, геттеры/сеттеры для свойств -- и все это с правильным свойством `[[Prototype]]`.
63
+
Такой вызов создаёт точную копию объекта `obj`, включая все свойства: перечисляемые и не перечисляемые, свойства, геттеры/сеттеры для свойств -- и все это с правильным свойством `[[Prototype]]`.
64
64
65
65
## Краткая история
66
66
@@ -70,13 +70,13 @@ let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescr
70
70
71
71
В силу исторических причин.
72
72
73
-
- Свойство `"prototype"` функции-конструктора существует еще с очень давних времен.
73
+
- Свойство `"prototype"` функции-конструктора существует ещё с очень давних времён.
74
74
- Позднее в 2012 году: `Object.create` появился в стандарте. Это давало возможность создавать объекты с указанным прототипом, но так же не позволяло устанавливать/получать его. Тогда браузеры реализовали нестандартный аксессор `__proto__`, который позволил устанавливать/получать прототип в любой время.
75
75
- Позднее и 2015 году: в стандарт были добавлены `Object.setPrototypeOf` и `Object.getPrototypeOf`. Фактически свойство `__proto__` было реализовано везде, так что оно попало Приложение Б стандарта, которое было опционально для не браузерных окружений.
76
76
77
77
Теперь мы знаем, что у нас есть все эти способы в нашем распоряжении.
78
78
79
-
Почему же `__proto__` был заменен на функции? Вопрос интересный, требующий от нас понимания, почему `__proto__` плох. Читайте далее, чтобы узнать ответ.
79
+
Почему же `__proto__` был заменён на функции? Вопрос интересный, требующий от нас понимания, почему `__proto__` плох. Читайте далее, чтобы узнать ответ.
80
80
81
81
```warn header="Не переопределяйте `[[Prototype]]`, кроме случаев, когда скорость не важна"
82
82
Технически, мы можем установить/получить `[[Prototype]]` в любое время. Но обычно мы устанавливаем прототип только раз во время создания объекта, а после не меняем: `rabbit` наследует от `animal`, и это не изменится.
@@ -101,13 +101,13 @@ obj[key] = "some value";
101
101
alert(obj[key]); // [object Object], не "some value"!
102
102
```
103
103
104
-
Если пользователь введет`__proto__`, присвоение проигнорируется!
104
+
Если пользователь введёт`__proto__`, присвоение проигнорируется!
105
105
106
106
И это не должно удивлять нас. Свойство `__proto__` особенное: оно должно быть либо объектом, либо `null`, а строка не может стать прототипом.
107
107
108
-
Но мы не *намеревались* реализовывать такое поведение, не так ли? Мы хотим хранить пары ключ/значение, и ключ с именем `"__proto__"` не был сохранен надлежащим образом. Так что это ошибка!
108
+
Но мы не *намеревались* реализовывать такое поведение, не так ли? Мы хотим хранить пары ключ/значение, и ключ с именем `"__proto__"` не был сохранён надлежащим образом. Так что это ошибка!
109
109
110
-
В примере последствия не так ужасны. Но в других случаях прототип может быть изменен, и код может выполниться совершенно неожиданным неправильным способом.
110
+
В примере последствия не так ужасны. Но в других случаях прототип может быть изменён, и код может выполниться совершенно неожиданным неправильным способом.
111
111
112
112
Что хуже всего -- разработчики не задумываются о такой возможности совсем. Это делает такие ошибки сложным для отлавливания или даже превращает их в уязвимости, особенно когда JavaScript используется на сервере.
113
113
@@ -140,13 +140,13 @@ obj[key] = "some value";
140
140
alert(obj[key]); // "some value"
141
141
```
142
142
143
-
`Object.create(null)`создает пустой объект без прототипа (свойство `[[Prototype]]` это `null`):
143
+
`Object.create(null)`создаёт пустой объект без прототипа (свойство `[[Prototype]]` это `null`):
144
144
145
145

146
146
147
-
Таким образом не будет унаследованного геттера/сеттера для `__proto__`. Теперь это свойство обрабатывается как обычное свойство, и пример приведенный выше работает правильно.
147
+
Таким образом не будет унаследованного геттера/сеттера для `__proto__`. Теперь это свойство обрабатывается как обычное свойство, и пример приведённый выше работает правильно.
148
148
149
-
Мы можем назвать такой объект "очень пустым" или "чистым словарным объектом", потому что они еще проще чем обычные объекты `{...}`.
149
+
Мы можем назвать такой объект "очень пустым" или "чистым словарным объектом", потому что они ещё проще чем обычные объекты `{...}`.
150
150
151
151
Недостаток в том, что у таких объектов не будет встроенных методов объекта, таких как `toString`:
Современные способы установки и прямого доступа к прототипу это:
177
177
178
-
-[Object.create(proto[, descriptors])](mdn:js/Object/create) -- создает пустой объект со свойством `[[Prototype]]`, указанным как `proto` (может быть `null`), и необязательными дескрипторами свойств.
178
+
-[Object.create(proto[, descriptors])](mdn:js/Object/create) -- создаёт пустой объект со свойством `[[Prototype]]`, указанным как `proto` (может быть `null`), и необязательными дескрипторами свойств.
179
179
-[Object.getPrototypeOf(obj)](mdn:js/Object.getPrototypeOf) -- возвращает свойство `[[Prototype]]` объекта `obj` (то же самое что и геттер `__proto__`).
180
180
-[Object.setPrototypeOf(obj, proto)](mdn:js/Object.setPrototypeOf) -- устанавливает свойство `[[Prototype]]` объекта `obj` как `proto` (то же самое что и сеттер `__proto__`).
181
181
182
-
Встроенный геттер/сеттер __proto__ не безопасен, если мы хотим использовать *созданные пользователями* ключи в объекте. Как минимум потому, что пользователь может ввести "proto" как ключ, от чего может возникнуть ошибка. Если повезет - последствия будут легкими, но обычно они непредсказуемы.
182
+
Встроенный геттер/сеттер __proto__ не безопасен, если мы хотим использовать *созданные пользователями* ключи в объекте. Как минимум потому, что пользователь может ввести "proto" как ключ, от чего может возникнуть ошибка. Если повезёт - последствия будут лёгкими, но обычно они непредсказуемы.
183
183
184
184
Тогда мы можем использовать либо `Object.create(null)` для создания "очень пустого" объекта, либо использовать коллекцию `Map`.
185
185
186
-
Также, `Object.create`дает нам легкий способ создать поверхностную копию объекты со всеми дескрипторами:
186
+
Также, `Object.create`даёт нам лёгкий способ создать поверхностную копию объекты со всеми дескрипторами:
187
187
188
188
```js
189
189
let clone =Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
190
190
```
191
191
192
192
193
-
-[Object.keys(obj)](mdn:js/Object/keys) / [Object.values(obj)](mdn:js/Object/values) / [Object.entries(obj)](mdn:js/Object/entries) -- возвращают массив всех перечисляемых собственных строковых имен/значений/пар ключ-значение.
194
-
-[Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) -- возвращает массив всех собственных символьных имен свойств.
195
-
-[Object.getOwnPropertyNames(obj)](mdn:js/Object/getOwnPropertyNames) -- возвращает массив всех собственных строковых имен свойств.
196
-
-[Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) -- возвращает массив всех собственных имен свойств.
193
+
-[Object.keys(obj)](mdn:js/Object/keys) / [Object.values(obj)](mdn:js/Object/values) / [Object.entries(obj)](mdn:js/Object/entries) -- возвращают массив всех перечисляемых собственных строковых имён/значений/пар ключ-значение.
194
+
-[Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) -- возвращает массив всех собственных символьных имён свойств.
195
+
-[Object.getOwnPropertyNames(obj)](mdn:js/Object/getOwnPropertyNames) -- возвращает массив всех собственных строковых имён свойств.
196
+
-[Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) -- возвращает массив всех собственных имён свойств.
197
197
-[obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty): возвращает `true`, если у `obj` есть собственное (не унаследованное) свойство с именем `key`.
198
198
199
199
Мы также ясно указали, что `__proto__` -- это геттер/сеттер для свойства `[[Prototype]]` и находится он в `Object.prototype`, как и другие методы.
0 commit comments