Skip to content

Commit 3b41c70

Browse files
committed
closes #803
1 parent a762933 commit 3b41c70

File tree

2 files changed

+58
-54
lines changed

2 files changed

+58
-54
lines changed

1-js/04-object-basics/01-object/article.md

Lines changed: 58 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ let user = {
103103
user.likes birds = true
104104
```
105105

106-
Так происходит, потому что точка требует, чтобы ключ был именован по правилам именования переменных. То есть не имел пробелов, не начинался с цифры и не содержал специальные символы, кроме `$` и `_`.
106+
JavaScript видит, что мы обращаемся к свойству `user.likes`, а затем идёт непонятное слово `birds`. В итоге синтаксическая ошибка.
107+
108+
Точка требует, чтобы ключ был именован по правилам именования переменных. То есть не имел пробелов, не начинался с цифры и не содержал специальные символы, кроме `$` и `_`.
107109

108110
Для таких случаев существует альтернативный способ доступа к свойствам через квадратные скобки. Такой способ сработает с любым именем свойства:
109111

@@ -208,42 +210,6 @@ let bag = {
208210

209211
Подведём итог: в большинстве случаев, когда имена свойств известны и просты, используется запись через точку. Если же нам нужно что-то более сложное, то мы используем квадратные скобки.
210212

211-
````smart header="Зарезервированные слова разрешено использовать как имена свойств"
212-
213-
Имя переменной не может совпадать с зарезервированными словами, такими как "for", "let", "return" и т.д.
214-
215-
Но для свойств объекта такого ограничения нет:
216-
217-
```js run
218-
let obj = {
219-
for: 1,
220-
let: 2,
221-
return: 3
222-
};
223-
224-
alert( obj.for + obj.let + obj.return ); // 6
225-
```
226-
227-
В принципе, разрешены любые имена свойств, но есть специальное свойство `__proto__`, которое по историческим причинам имеет особое поведение. Например, его значение всегда должно быть объектом, и мы не можем установить для него никакое другое значение:
228-
229-
```js run
230-
let obj = {};
231-
obj.__proto__ = 5;
232-
alert(obj.__proto__); // [object Object], работает не так, как мы ожидали
233-
```
234-
235-
Как мы видим, присвоение примитивного значения `5` игнорируется.
236-
237-
Это может стать источником ошибок и даже уязвимостей, если мы намереваемся хранить в объекте произвольные пары "ключ:значение" и позволяем посетителям указывать ключи.
238-
239-
Посетитель может указать `__proto__` в качестве ключа, и логика присваивания будет нарушена (как показано выше).
240-
241-
Есть способ заставить объекты обрабатывать `__proto__` как обычное свойство. Мы поговорим о нём позже, а пока нам нужно узнать больше об объектах.
242-
243-
Также существует другая структура данных [Map](info:map-set), которая поддерживает произвольные ключи. Мы изучим её в главе <info:map-set>.
244-
````
245-
246-
247213
## Свойство из переменной
248214

249215
В реальном коде часто нам необходимо использовать существующие переменные как значения для свойств с тем же именем.
@@ -288,7 +254,61 @@ let user = {
288254
};
289255
```
290256

291-
## Проверка существования свойства
257+
## Ограничения на имена свойств
258+
259+
Мы можем использовать только строки и символы в качестве ключей свойств. Все другие типы данных будут автоматически преобразованы к строке.
260+
261+
Например, если использовать как ключ число `0`, то оно превратится в строку `"0"`:
262+
263+
```js run
264+
let obj = {
265+
0: "Тест" // то же самое что и "0": "Тест"
266+
};
267+
268+
// обе функции alert выведут одно и то же свойство (число 0 преобразуется в строку "0")
269+
alert( obj["0"] ); // Тест
270+
alert( obj[0] ); // Тест (то же свойство)
271+
```
272+
273+
**Зарезервированные слова разрешено использовать как имена свойств.**
274+
275+
Как мы уже знаем, имя переменной не может совпадать с зарезервированными словами, такими как "for", "let", "return" и т.д.
276+
277+
Но для свойств объекта такого ограничения нет:
278+
279+
```js run
280+
let obj = {
281+
for: 1,
282+
let: 2,
283+
return: 3
284+
};
285+
286+
alert( obj.for + obj.let + obj.return ); // 6
287+
```
288+
289+
**В принципе, разрешены любые имена свойств, но есть специальное свойство `__proto__`, которое по историческим причинам имеет особое поведение.**
290+
291+
Например, его значение всегда должно быть объектом:
292+
293+
```js run
294+
let obj = {};
295+
obj.__proto__ = 5;
296+
alert(obj.__proto__); // [object Object], работает не так, как мы ожидали
297+
```
298+
299+
Как мы видим, присвоение примитивного значения `5` игнорируется.
300+
301+
Мы более подробно исследуем происходящее свойство `__proto__` позже, в главе [](info:prototype-inheritance).
302+
303+
Сейчас важно знать, что такое поведение `__proto__` может стать источником ошибок и даже уязвимостей, если мы намереваемся хранить в объекте произвольные данные и позволяем посетителям указывать ключи.
304+
305+
Посетитель может указать `"__proto__"` в качестве ключа, и логика присваивания будет нарушена (как показано выше).
306+
307+
Позже мы изучим, как обойти эту проблему:
308+
1. Можно заставить объект обрабатывать `__proto__` как обычное свойство, мы это увидим в главе [](info:prototype-methods).
309+
2. Есть другая структура данных [Map](info:map-set), которую мы изучим в главе <info:map-set>, она поддерживает произвольные ключи.
310+
311+
## Проверка существования свойства, оператор "in"
292312

293313
Особенность объектов в том, что можно получить доступ к любому свойству. Даже если свойства не существует - ошибки не будет! При обращении к свойству, которого нет, возвращается `undefined`. Это позволяет просто проверить существование свойства - сравнением его с `undefined`:
294314

1-js/04-object-basics/03-symbol/article.md

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -179,22 +179,6 @@ alert( clone[id] ); // 123
179179

180180
Здесь нет никакого парадокса или противоречия. Так и задумано. Идея заключается в том, что, когда мы клонируем или объединяем объекты, мы обычно хотим скопировать *все* свойства (включая такие свойства с ключами-символами, как, например, `id` в примере выше).
181181

182-
````smart header="Ключи других типов принудительно преобразуются к строке"
183-
Мы можем использовать только строки и символы в качестве ключей свойств. Все другие типы данных будут автоматически преобразованы к строке.
184-
185-
Например, число `0`, будучи использованным как ключ свойства, превратится в строку `"0"`:
186-
187-
```js run
188-
let obj = {
189-
0: "Тест" // то же самое что и "0": "Тест"
190-
};
191-
192-
// обе функции alert выведут одно и то же свойство (число 0 преобразовывается в строку "0")
193-
alert( obj["0"] ); // Тест
194-
alert( obj[0] ); // Тест (то же свойство)
195-
```
196-
````
197-
198182
## Глобальные символы
199183

200184
Итак, как мы видели, обычно все символы уникальны, даже если их имена совпадают. Но иногда мы наоборот хотим, чтобы символы с одинаковыми именами были одной сущностью. Например, разные части нашего приложения хотят получить доступ к символу `"id"`, подразумевая именно одно и то же свойство.

0 commit comments

Comments
 (0)