1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
---
title: Property accessors
slug: Web/JavaScript/Reference/Operators/Property_Accessors
translation_of: Web/JavaScript/Reference/Operators/Property_Accessors
---
<div>{{jsSidebar("Operators")}}</div>
<p>Доступ к свойствам объекта можно получить, используя точечную и скобочную записи.</p>
<p>{{EmbedInteractiveExample("pages/js/expressions-propertyaccessors.html", "taller")}}</p>
<h2 id="Синтаксис">Синтаксис</h2>
<pre class="syntaxbox">object.property
object["property"]
</pre>
<h2 id="Описание">Описание</h2>
<p>Можно думать об объекте как об ассоциативном массиве (или <em>карте, словаре, хэш-таблице, таблице поиска</em>). <em>Ключи</em> в таком массиве - это имена свойств объекта.</p>
<p>Когда речь идёт о свойствах объекта, обычно различают собственно свойства и методы. Однако разделение свойство/метод это не более чем условность. Метод - это просто свойство, которое можно вызвать (например, если оно содержит ссылку на {{jsxref("Function", "функцию")}} в качестве значения.</p>
<p>Есть два способа доступа к свойствам: точечная и скобочная записи.</p>
<h3 id="Точечная_запись">Точечная запись</h3>
<p class="brush: js">В записи <code>object.property</code>, <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">property</span></font> должно быть действительным <a href="/ru/docs/%D0%A1%D0%BB%D0%BE%D0%B2%D0%B0%D1%80%D1%8C/Identifier">идентификатором</a>. (В стандарте ECMAScript, имена свойств технически называются "IdentifierNames", а не "Identifiers", поэтому зарезервированные слова могут быть использованы в их качестве, но это не рекомендуется). Например, <code>object.$1</code> является верной записью, а <code>object.1</code> - нет.</p>
<pre class="brush: js">const variable = <var>object</var>.<var>property_name;</var>
<var>object</var>.<var>property_name</var> = value;
</pre>
<pre class="brush: js">const object = {};
object.$1 = 'foo';
console.log(object.$1); // 'foo'
object.1 = 'bar'; // SyntaxError
console.log(object.1); // SyntaxError</pre>
<p>Здесь метод с именем <code>createElement</code> считывается с объекта <code>document</code> и вызывается.</p>
<pre class="brush: js">document.createElement('pre')</pre>
<p>Если вы хотите вызвать метод на численном литерале, не имеющий части с экспонентой или точки, отделяющей дробную часть, нужно ставить пробел перед точкой, являющейся частью обращения к этому методу, чтобы интерпретатор не посчитал, что это точка отделяет дробную часть числа (или использовать другие способы этого избежать).</p>
<pre class="brush: js">// SyntaxError, здесь считается, что 77. это число,
// поэтому такая запись эквивалентна (77.)toExponentional()
// что является ошибкой
77.toExponentional()
// Рабочие варианты:
77.toExponential()
77
.toExponential()
;(77).toExponential()
// Здесь первая точка относится к числу, вторая вызывает метод
// то есть эта запись равносильна (77.).toExponential()
77..toExponential()
// Эквивалентно (77.0).toExponential()
77.0.toExponential()</pre>
<h3 id="Скобочная_запись">Скобочная запись</h3>
<p class="brush: js">В записи <code>object[property_name]</code>, <em><code>property_name</code> - </em>это выражение, вычисляющееся в строку или <a href="/ru/docs/%D0%A1%D0%BB%D0%BE%D0%B2%D0%B0%D1%80%D1%8C/Symbol">символ</a>. Это может быть любая строка, не обязательно действительный идентификатор, например <code>'1foo'</code>, '<code>!bar!'</code> или даже <code>' '</code> (пробел).</p>
<pre class="brush: js">const variable = object[property_name]
object[property_name] = value</pre>
<p>Пример, аналогичный примеру в предыдущем пункте:</p>
<pre class="brush: js">document['createElement']('pre');
</pre>
<p>Пробел перед скобкой допускается:</p>
<pre class="brush: js">document ['createElement']('pre')</pre>
<h3 id="Имена_свойств">Имена свойств</h3>
<p>Имена свойств могут быть строками или <a href="/ru/docs/%D0%A1%D0%BB%D0%BE%D0%B2%D0%B0%D1%80%D1%8C/Symbol">символами</a>. Любое другое значение приводится к строке. Следующий код выводит <code>'value'</code>, поскольку число <code>1</code> приводится к строке <code>'1'</code>.</p>
<pre class="brush: js">const object = {}
object['1'] = 'value'
console.log(object[1])</pre>
<p>Этот пример также выводит <code>'value',</code> так как и <code>foo</code>, и <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">bar</span></font> приводятся к одной и той же строке.</p>
<pre class="brush: js">const foo = {unique_prop: 1}
const bar = {unique_prop: 2}
const object = {}
object[foo] = 'value';
console.log(object[bar]);
</pre>
<p>В движке <a href="/en-US/docs/Mozilla/Projects/SpiderMonkey">SpiderMonkey</a> JavaScript это строка <code>'[object Object]'</code>.</p>
<h3 id="Привязка_методов">Привязка методов</h3>
<p>Метод не привязан к содержащему его объекту. Это значит, что значение <code>this</code> в методах объекта не всегда указывает на него. Вместо этого, <code>this</code> "передаётся" при вызове метода. Смотрите подробнее <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/this#Method_binding">this</a></code>.</p>
<h2 id="Примеры">Примеры</h2>
<h3 id="Скобочная_запись_или_eval">Скобочная запись или <code>eval</code></h3>
<p>Новички JavaScript часто делают ошибку, используя <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval">eval</a> там, где можно просто использовать скобочную запись.</p>
<p>Например, следующий синтаксис можно часто увидеть в скриптах.</p>
<pre class="brush: js">x = eval('document.forms.form_name.elements.' + strFormControl + '.value');
</pre>
<p>Функция <code>eval()</code> очень медленная и её использования следует избегать, когда это возможно. Кроме того, строка <code>strFormControl</code> при таком использовании обязаны содержать действительный идентификатор, что не является обязательным для <code>id</code> полей формы, то есть, например, поле с id <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">1</span></font> не получится получить такой записью. Лучше вместо этого использовать скобочную запись:</p>
<pre class="brush: js">x = document.forms["form_name"].elements[strFormControl].value;
</pre>
<h2 id="Спецификации">Спецификации</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Спецификация</th>
<th scope="col">Статус</th>
<th scope="col">Комментарий</th>
</tr>
<tr>
<td>{{SpecName('ES6', '#sec-property-accessors', 'Property Accessors')}}</td>
<td>{{Spec2('ES6')}}</td>
<td></td>
</tr>
<tr>
<td>{{SpecName('ES5.1', '#sec-11.2.1', 'Property Accessors')}}</td>
<td>{{Spec2('ES5.1')}}</td>
<td></td>
</tr>
<tr>
<td>{{SpecName('ES1', '#sec-11.2.1', 'Property Accessors')}}</td>
<td>{{Spec2('ES1')}}</td>
<td>Изначальное определение.</td>
</tr>
</tbody>
</table>
<h2 id="Поддержка_браузерами">Поддержка браузерами</h2>
<p>{{Compat}}</p>
<h2 id="Смотрите_также">Смотрите также</h2>
<ul>
<li>{{jsxref("Object")}}</li>
</ul>
|