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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
|
---
title: Работа с объектами
slug: Web/JavaScript/Guide/Working_with_Objects
translation_of: Web/JavaScript/Guide/Working_with_Objects
---
<p>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Keyed_collections", "Web/JavaScript/Guide/Details_of_the_Object_Model")}}</p>
<p class="summary">JavaScript спроектирован на основе простой парадигмы. В основе концепции лежат простые объекты. Объект <span style="line-height: 1.5;">—</span> это набор свойств, и каждое свойство состоит из имени и значения, ассоциированного с этим именем. Значением свойства может быть функция, которую можно назвать <em>методом</em> объекта. В дополнение к встроенным в браузер объектам, вы можете определить свои собственные объекты. Эта глава описывает как пользоваться объектами, свойствами, функциями и методами, а также как создавать свои собственные объекты.</p>
<h2 id="Обзор_объектов">Обзор объектов</h2>
<p>Объекты в JavaScript, как и во многих других языках программирования, похожи на объекты реальной жизни. Концепцию объектов JavaScript легче понять, проводя параллели с реально существующими в жизни объектами.</p>
<p>В JavaScript объект — это самостоятельная единица, имеющая свойства и определенный тип. Сравним, например, с чашкой. У чашки есть цвет, форма, вес, материал, из которого она сделана, и т.д. Точно так же, объекты JavaScript имеют свойства, которые определяют их характеристики.</p>
<h2 id="Объекты_и_свойства">Объекты и свойства</h2>
<p>В JavaScript объект имеет свойства, ассоциированные с ним. Свойство объекта можно понимать как переменную, закрепленную за объектом. Свойства объекта в сущности являются теми же самыми переменными JavaScript, за тем исключением, что они закреплены за объектом. Свойства объекта определяют его характеристики. Получить доступ к свойству объекта можно с помощью точечной записи:</p>
<div style="margin-right: 270px;">
<pre class="brush: js">objectName.propertyName
</pre>
</div>
<p>Как и все переменные JavaScript, имя объекта (которое тоже может быть переменной) и имя свойства являются чувствительными к регистру. Вы можете определить свойство указав его значение. Например, давайте создадим объект <code>myCar</code> и определим его свойства <code>make</code>, <code>model</code>, и <code>year</code> следующим образом:</p>
<pre class="brush: js">var myCar = new Object();
myCar.make = "Ford";
myCar.model = "Mustang";
myCar.year = 1969;
</pre>
<p>Неопределенные свойства объекта являются {{jsxref("undefined")}} (а не {{jsxref("null")}}).</p>
<pre class="brush: js line-numbers language-js"><code class="language-js">myCar<span class="punctuation token">.</span>color<span class="punctuation token">;</span> <span class="comment token">// undefined</span></code></pre>
<p>Свойства объектов JavaScript также могут быть доступны или заданы с использованием скобочной записи (более подробно см. <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/Property_Accessors">property accessors</a>). Объекты иногда называются <em>ассоциативными массивами</em>, поскольку каждое свойство связано со строковым значением, которое можно использовать для доступа к нему. Так, например, вы можете получить доступ к свойствам объекта <code>myCar </code>следующим образом:</p>
<pre class="brush: js">myCar["make"] = "Ford";
myCar["model"] = "Mustang";
myCar["year"] = 1969;
</pre>
<p>Имена свойств объекта могут быть строками JavaScript, или тем, что может быть сконвертировано в строку, включая пустую строку. Как бы то ни было, доступ к любому имени свойства, которое содержит невалидный JavaScript идентификатор (например, имя свойства содержит в себе пробел и тире или начинается с цифры), может быть получен с использованием квадратных скобок. Этот способ записи также полезен, когда имена свойств должны быть динамически определены (когда имя свойства не определено до момента исполнения). Примеры далее:</p>
<pre class="brush: js">var myObj = new Object(),
str = "myString",
rand = Math.random(),
obj = new Object();
myObj.type = "Dot syntax";
myObj["date created"] = "String with space";
myObj[str] = "String value";
myObj[rand] = "Random Number";
myObj[obj] = "Object";
myObj[""] = "Even an empty string";
console.log(myObj);
</pre>
<p>Обратите внимание, что все ключи с квадратными скобками преобразуются в тип String, поскольку объекты в JavaScript могут иметь в качестве ключа только тип String. Например, в приведенном выше коде, когда ключ <code>obj</code> добавляется в <code>myObj</code>, JavaScript вызывает метод <code>obj.toString ()</code> и использует эту результирующую строку в качестве нового ключа.</p>
<p>Вы также можете получить доступ к свойствам, используя значение строки, которое хранится в переменной:</p>
<div style="width: auto;">
<pre class="brush: js">var propertyName = "make";
myCar[propertyName] = "Ford";
propertyName = "model";
myCar[propertyName] = "Mustang";
</pre>
</div>
<p>Вы можете пользоваться квадратными скобками в конструкции <a class="internal" href="/ru/docs/JavaScript/Guide/Statements#for...in_Statement" title="ru/docs/JavaScript/Guide/Statements#for...in Statement">for...in</a> чтобы выполнить итерацию всех свойств объекта, для которых она разрешена. Чтобы показать как это работает, следующая функция показывает все свойства объекта, когда вы передаете в нее сам объект и его имя как аргументы функции:</p>
<pre class="brush: js">function showProps(obj, objName) {
var result = "";
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
result += objName + "." + i + " = " + obj[i] + "\n";
}
}
return result;
}
</pre>
<p>Так что если вызвать эту функцию вот так <code>showProps(myCar, "myCar"),</code> то получим результат:</p>
<pre class="brush: js">myCar.make = Ford
myCar.model = Mustang
myCar.year = 1969</pre>
<h2 id="Перечисление_всех_свойств_объекта">Перечисление всех свойств объекта</h2>
<p>Начиная с <a href="/ru/docs/JavaScript/ECMAScript_5_support_in_Mozilla" title="ru/docs/JavaScript/ECMAScript 5 support in Mozilla">ECMAScript 5</a>, есть три способа перечислить все свойства объекта (получить их список):</p>
<ul>
<li>циклы <a href="/ru/docs/JavaScript/Reference/Statements/for...in" title="/ru/docs/JavaScript/Reference/Statements/for...in">for...in </a><br>
Этот метод перебирает все перечисляемые свойства объекта и его цепочку прототипов</li>
<li><a href="/ru/docs/JavaScript/Reference/Global_Objects/Object/keys" title="ru/docs/JavaScript/Reference/Global Objects/Object/keys">Object.keys(o)</a><br>
Этот метод возвращает массив со всеми собственными (те, что в цепочке прототипов, не войдут в массив) именами перечисляемых свойств объекта <code>o</code>.</li>
<li><a href="/ru/docs/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames" title="ru/docs/JavaScript/Reference/Global Objects/Object/getOwnPropertyNames">Object.getOwnPropertyNames(o)</a><br>
Этот метод возвращает массив содержащий все имена своих свойств (перечисляемых и неперечисляемых) объекта <code>o</code>.</li>
</ul>
<p>До ECMAScript 5 не было встроенного способа перечислить все свойства объекта. Однако это можно сделать с помощью следующей функции:</p>
<pre class="brush: js">function listAllProperties(o){
var objectToInspect;
var result = [];
for(objectToInspect = o; objectToInspect !== null; objectToInspect = Object.getPrototypeOf(objectToInspect)){
result = result.concat(Object.getOwnPropertyNames(objectToInspect));
}
return result;
}
</pre>
<p>Это может быть полезно для обнаружения скрытых (hidden) свойств (свойства в цепочке прототипа, которые недоступны через объект, в случае, если другое свойство имеет такое же имя в предыдущем звене из цепочки прототипа). Перечислить доступные свойства можно, если удалить дубликаты из массива.</p>
<h2 id="Создание_новых_объектов">Создание новых объектов</h2>
<p>JavaScript содержит набор встроенных объектов. Также вы можете создавать свои объекты. Начиная с JavaScript 1.2, вы можете создавать объект с помощью инициализатора объекта. Другой способ <span style="line-height: 1.5;">—</span> создать функцию-конструктор и сделать экземпляр объекта с помощью этой функции и оператора <code>new</code>.</p>
<h3 id="Использование_инициализаторов_объекта">Использование инициализаторов объекта</h3>
<p>Помимо создания объектов с помощью функции-конструктора вы можете создавать объекты и другим, особым способом. Фактически, вы можете записать объект синтаксически, и он будет создан интерпретатором автоматически во время выполнения. Эта синтаксическая схема приведена ниже:</p>
<pre class="brush: js">var obj = { property_1: value_1, // property_# may be an identifier...
2: value_2, // or a number...
// ...,
"property n": value_n }; // or a string
</pre>
<p>здесь <code>obj</code> <span style="line-height: 1.5;">—</span> это имя нового объекта, каждое <code>property_i</code> <span style="line-height: 1.5;">—</span> это идентификатор (имя, число или строковый литерал), и каждый <code>value_i</code> <span style="line-height: 1.5;">—</span> это значения, назначенные <em><code>property_i</code></em>. Имя <code>obj</code> и ссылка объекта на него необязательна; если далее вам не надо будет ссылаться на данный объект, то вам не обязательно назначать объект переменной. (Обратите внимание, что вам потребуется обернуть литерал объекта в скобки, если объект находится в месте, где ожидается инструкция, чтобы интерпретатор не перепутал его с блоком.)</p>
<p>Если объект создан при помощи инициализатора объектов на высшем уровне скрипта, то JavaScript интерпретирует объект каждый раз, когда анализирует выражение, содержащее объект, записанный как литерал. Плюс, если пользоваться функцией инициализатором, то он будет создаваться каждый раз, когда функция вызывается.</p>
<p>Следующая инструкция создает объект и назначает его переменной <code>x</code>, когда выражение <code>cond</code> истинно.</p>
<pre class="brush: js">if (cond) var x = {hi: "there"};
</pre>
<p>Следующий пример создает объект <code>myHonda</code> с тремя свойствами. Заметьте, что свойство <code>engine</code> <span style="line-height: 1.5;">—</span> это также объект со своими собственными свойствами.</p>
<pre class="brush: js">var myHonda = {
color: "red",
wheels: 4,
engine: {
cylinders: 4,
size: 2.2
}
};
</pre>
<p>Вы также можете использовать инициализатор объекта для создания массивов. Смотрите {{ web.link("Values%2C_variables%2C_and_literals#Array_literals", "array literals") }}.</p>
<p>До JavaScript 1.1 не было возможности пользоваться инициализаторами объекта. Единственный способ создавать объекты <span style="line-height: 1.5;">—</span> это пользоваться функциями-конструкторами или функциями других объектов, предназначенных для этой цели. Смотрите {{ anch("Using a constructor function") }}.</p>
<h3 id="Использование_функции_конструктора">Использование функции конструктора</h3>
<p>Другой способ создать объект в два шага описан ниже:</p>
<ol>
<li>Определите тип объекта, написав функцию-конструктор. Название такой функции, как правило, начинается с заглавной буквы.</li>
<li>Создайте экземпляр объекта с помощью ключевого слова <code>new</code>.</li>
</ol>
<p>Чтобы определить тип объекта создайте функцию, которая определяет тип объекта, его имя, свойства и методы. Например предположим, что вы хотите создать тип объекта для описания машин. Вы хотите, чтобы объект этого типа назывался <code>car</code>, и вы хотите, чтобы у него были свойства make, model, и year. Чтобы сделать это, напишите следующую функцию:</p>
<pre class="brush: js">function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
</pre>
<p>Заметьте, что используется <code>this</code> чтобы присвоить значения (переданные как аргументы функции) свойствам объекта.</p>
<p>Теперь вы можете создать объект, называемый <code>mycar</code>, следующим образом:</p>
<pre class="brush: js">var mycar = new Car("Eagle", "Talon TSi", 1993);
</pre>
<p>Эта инструкция создает объект типа Car со ссылкой <code>mycar</code> и присваивает определенные значения его свойствам. Значением <code>mycar.make </code>станет строка "Eagle", <code>mycar.year</code> <span style="line-height: 1.5;">—</span> это целое число 1993, и так далее.</p>
<p>Вы можете создать столько объектов <code>car,</code> сколько нужно, просто вызывая <code>new</code>. Например:</p>
<pre class="brush: js">var kenscar = new Car("Nissan", "300ZX", 1992);
var vpgscar = new Car("Mazda", "Miata", 1990);
</pre>
<p>Объект может иметь свойство, которое будет другим объектом. Например, далее определяется объект типа <code>Person</code> следующим образом:</p>
<pre class="brush: js">function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
</pre>
<p>и затем создать два новых экземпляра объектов <code>Person</code> как показано далее:</p>
<pre class="brush: js">var rand = new Person("Rand McKinnon", 33, "M");
var ken = new Person("Ken Jones", 39, "M");
</pre>
<p>Затем, вы можете переписать определение <code>car</code> и включить в него свойство <code>owner</code>, которому назначить объект <code>person</code> следующим образом:</p>
<pre class="brush: js">function Car(make, model, year, owner) {
this.make = make;
this.model = model;
this.year = year;
this.owner = owner;
}
</pre>
<p>Затем, чтобы создать экземпляры новых объектов, выполните следующие инструкции:</p>
<pre class="brush: js">var car1 = new Car("Eagle", "Talon TSi", 1993, rand);
var car2 = new Car("Nissan", "300ZX", 1992, ken);
</pre>
<p>Заметьте, что вместо того, чтобы передавать строку, литерал или целое число при создании новых объектов, в выражениях выше передаются объекты <code>rand</code> и <code>ken</code> как аргумент функции. Теперь, если вам нужно узнать имя владельца car2, это можно сделать следующим образом:</p>
<pre class="brush: js">car2.owner
</pre>
<p>Заметьте, что в любое время вы можете добавить новое свойство ранее созданному объекту. Например, выражение</p>
<pre class="brush: js">car1.color = "black";
</pre>
<p>добавляет свойство <code>color</code> к car1, и устанавливает его значение равным "black." Как бы там ни было, это не влияет на любые другие объекты. Чтобы добавить новое свойство всем объектам одного типа, вы должны добавить свойство в определение типа объекта <code>car</code>.</p>
<h3 id="Использование_метода_Object.create">Использование метода Object.create</h3>
<p>Объекты также можно создавать с помощью метода <code>Object.create</code>. Этот метод очень удобен, так как позволяет вам указывать объект прототип для нового вашего объекта без определения функции конструктора.</p>
<pre class="brush: js">// список свойств и методов для Animal
var Animal = {
type: 'Invertebrates', // Значение type по умолчанию
displayType: function() { // Метод отображающий тип объекта Animal
console.log(this.type);
}
};
// Создаем объект Animal
var animal1 = Object.create(Animal);
animal1.displayType(); // Выведет:Invertebrates
// Создаем объект Animal и присваиваем ему type = Fishes
var fish = Object.create(Animal);
fish.type = 'Fishes';
fish.displayType(); // Выведет:Fishes</pre>
<h2 id="Наследование">Наследование</h2>
<p>Все объекты в JavaScript наследуются как минимум от другого объекта. Объект, от которого произошло наследование называется прототипом, и унаследованные свойства могут быть найдены в объекте <code>prototype</code> конструктора.</p>
<h2 id="Индексы_свойств_объекта">Индексы свойств объекта</h2>
<p>В JavaScript 1.0 вы можете сослаться на свойства объекта либо по его имени, либо по его порядковому индексу. В JavaScript 1.1 и позже, если вы изначально определили свойство по имени, вы всегда должны ссылаться на него по его имени, и если вы изначально определили свойство по индексу, то должны ссылаться на него по его индексу.</p>
<p>Это ограничение налагается когда вы создаете объект и его свойства с помощью функции конструктора (как мы это делали ранее с типом <em>Car </em>) и когда вы определяете индивидуальные свойства явно (например, <code>myCar.color = "red"</code>). Если вы изначально определили свойство объекта через индекс, например <code>myCar[5] = "25 mpg"</code>, то впоследствии сослаться на это свойство можно только так <code>myCar[5]</code>.</p>
<p>Исключение из правил <span style="line-height: 1.5;">—</span> объекты, отображаемые из HTML, например массив<code> forms</code>. Вы всегда можете сослаться на объекты в этих массивах или используя их индекс (который основывается на порядке появления в HTML документе), или по их именам (если таковые были определены). Например, если второй html-тег <code><FORM></code> в документе имеет значение атрибута <code>NAME</code> равное "myForm", вы можете сослаться на эту форму вот так: <code>document.forms[1]</code> или <code>document.forms["myForm"]</code> или <code>document.myForm</code>.</p>
<h2 id="Определение_свойств_для_типа_объекта">Определение свойств для типа объекта</h2>
<p>Вы можете добавить свойство к ранее определенному типу объекта воспользовавшись специальным свойством <code>prototype</code>. Через <code>prototype</code> создается свойство, единое для всех объектов данного типа, а не одного экземпляра этого типа объекта. Следующий код демонстрирует это, добавляя свойство <code>color</code> ко всем объектам типа <code>car</code>, а затем присваивая значение свойству <code>color</code> объекта<code> car1</code>.</p>
<pre class="brush: js">Car.prototype.color = null;
car1.color = "black";
</pre>
<p>Смотрите <a href="/ru/docs/JavaScript/Reference/Global_Objects/Function/prototype" title="ru/docs/JavaScript/Reference/Global Objects/Function/prototype"><code>свойство prototype</code></a> объекта <code>Function</code> в <a href="/ru/docs/JavaScript/Reference" title="ru/docs/JavaScript/Reference">Справочнике JavaScript </a>для получения деталей.</p>
<h2 id="Определение_методов">Определение методов</h2>
<p><em>Метод</em> <span style="line-height: 1.5;">—</span> это функция, ассоциированная с объектом или, проще говоря, метод <span style="line-height: 1.5;">—</span> это свойство объекта, являющееся функцией. Методы определяются так же, как и обычные функции, за тем исключением, что они присваиваются свойству объекта. Например вот так:</p>
<pre class="brush: js">objectName.methodname = function_name;
var myObj = {
myMethod: function(params) {
// ...do something
}
};
</pre>
<p>где <code>objectName</code> <span style="line-height: 1.5;">— </span>это существующий объект, <code>methodname</code> <span style="line-height: 1.5;">— </span>это имя, которое вы присваиваете методу, и <code>function_name</code> <span style="line-height: 1.5;">—</span> это имя самой функции.</p>
<p>Затем вы можете вызвать метод в контексте объекта следующим образом:</p>
<pre class="brush: js">object.methodname(params);
</pre>
<p>Вы можете определять методы для типа объекта, включая определение метода в функцию конструктора объекта. Например, вы можете определить функцию, которая форматирует и отображает свойства до этого определенных объектов <code>car</code>. Например,</p>
<pre class="brush: js">function displayCar() {
var result = "A Beautiful " + this.year + " " + this.make
+ " " + this.model;
pretty_print(result);
}
</pre>
<p>где <code>pretty_print</code> <span style="line-height: 1.5;">—</span> это функция отображения горизонтальной линии и строки. Заметьте, что использование <code>this</code> позволяет ссылаться на объект, которому принадлежит метод.</p>
<p>Вы можете сделать эту функцию методом <code>car,</code> добавив инструкцию</p>
<pre class="brush: js">this.displayCar = displayCar;
</pre>
<p>к определению объекта. Таким образом, полное определение <code>car</code> примет следующий вид:</p>
<pre class="brush: js">function Car(make, model, year, owner) {
this.make = make;
this.model = model;
this.year = year;
this.owner = owner;
this.displayCar = displayCar;
}
</pre>
<p>Теперь вы можете вызвать метод <code>displayCar</code> для каждого из объектов как показано ниже:</p>
<pre class="brush: js">car1.displayCar();
car2.displayCar();
</pre>
<h2 id="Использование_this_для_ссылки_на_объект">Использование <code>this</code> для ссылки на объект</h2>
<p>В JavaScript есть специальное ключевое слово this, которое вы можете использовать внутри метода, чтобы ссылаться на текущий объект. Предположим, у вас есть функция validate, которая сверяет свойство value, переданного ей объекта с некоторыми верхним и нижним значениями:</p>
<pre class="brush: js">function validate(obj, lowval, hival) {
if ((obj.value < lowval) || (obj.value > hival))
alert("Invalid Value!");
}
</pre>
<p>Вы можете вызвать эту функцию <code>validate</code> в каждом элементе формы, в обработчике события <code>onchange</code>. Используйте <code>this</code> для доступа к этому элементу, как это сделано ниже:</p>
<pre class="brush: html"><input type="text" name="age" size="3"
onChange="validate(this, 18, 99)">
</pre>
<p>В общем случае, <code>this</code> ссылается на объект, вызвавший метод.</p>
<p>Через <code>this</code> можно обратиться и к родительской форме элемента, воспользовавшись свойством <code>form</code>. В следующем примере форма <code>myForm</code> содержит элемент ввода <code>Text </code>и кнопку <code>button1</code>. Когда пользователь нажимает кнопку, значению объекта <code>Text</code> назначается имя формы. Обработчик событий кнопки <code>onclick</code> пользуется <code>this.form</code> чтобы сослаться на текущую форму, <code>myForm</code>.</p>
<pre class="brush: html"><form name="myForm">
<p><label>Form name:<input type="text" name="text1" value="Beluga"></label>
<p><input name="button1" type="button" value="Show Form Name"
onclick="this.form.text1.value = this.form.name">
</p>
</form></pre>
<h2 id="Определение_геттеров_и_сеттеров">Определение геттеров и сеттеров</h2>
<p><em><a href="/ru/docs/Web/JavaScript/Reference/Functions/get">Геттер </a>(от англ. get - получить) </em><span style="line-height: 1.5;">—</span><em> </em>это метод, который получает значение определенного свойства. <em><a href="/ru/docs/Web/JavaScript/Reference/Functions/set">Сеттер </a>(от англ. set </em><span style="line-height: 1.5;">—</span><em> присвоить)</em> <span style="line-height: 1.5;">—</span> это метод, который присваивает значение определенному свойству объекта. Вы можете определить геттеры и сеттеры для любых из встроенных или определенных вами объектов, которые поддерживают добавление новых свойств. Синтаксис определения геттеров и сеттеров использует литеральный синтаксис объектов.</p>
<p>Ниже проиллюстрировано, как могут работать геттеры и сеттеры в объекте определенном пользователем:</p>
<pre class="brush: js"><code>var o = {
a: 7,
get b() {
return this.a + 1;
},
set c(x) {
this.a = x / 2;
}
};
console.log(o.a); // 7
console.log(o.b); // 8
o.c = 50;
console.log(o.a); // 25</code></pre>
<p>Объект <code>o</code> получит следующие свойства:</p>
<ul>
<li><code>o.a</code> — число</li>
<li><code>o.b</code> — геттер, который возвращает <code>o.a</code> плюс 1</li>
<li><code>o.c</code> — сеттер, который присваивает значение <code>o.a</code> половине значения которое передано в <code>o.c</code></li>
</ul>
<p>Следует особо отметить, что имена функций, указанные в литеральной форме "[gs]et <em>propertyName</em>() { }" не будут в действительности являться именами геттера и сеттера. Чтобы задать в качестве геттера и сеттера функции с явно определенными именами, используйте метод <code><a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty" title="en-US/docs/Core JavaScript 1.5 Reference/Global
Objects/Object/defineProperty">Object.defineProperty</a></code> (или его устаревший аналог <code><a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineGetter" title="en-US/docs/Core JavaScript 1.5 Reference/Global
Objects/Object/defineGetter">Object.prototype.__defineGetter__</a></code>).</p>
<p>В коде ниже показано, как с помощью геттера и сеттера можно расширить прототип объекта {{jsxref("Date")}} и добавить ему свойство <code>year,</code> которое будет работать у всех экземпляров класса <code>Date</code>. Этот код использует существующие методы класса <code>Date</code> - <code>getFullYear</code> и <code>setFullYear</code> для работы геттера и сеттера.</p>
<p>Определение геттера и сеттера для свойства <code>year</code>:</p>
<pre class="brush: js"><code>var d = Date.prototype;
Object.defineProperty(d, 'year', {
get: function() { return this.getFullYear(); },
set: function(y) { this.setFullYear(y); }
});</code></pre>
<p>Использование свойства <code>year</code> заданного геттером и сеттером:</p>
<pre class="brush: js"><code>var now = new Date();
console.log(now.year); // 2000
now.year = 2001; // 987617605170
console.log(now);
// Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001</code></pre>
<p>В принципе, геттеры и сеттеры могут быть либо:</p>
<ul>
<li>определены при использовании {{ web.link("#Использование_инициализаторов_объекта", "Инициализаторов объекта") }}, или</li>
<li>добавлены существующему объекту в любой момент, при использовании методов добавления геттеров и сеттеров.</li>
</ul>
<p>Когда определение геттера и сеттера использует {{ web.link("#Использование_инициализаторов_объекта", "инициализаторы объекта") }}, все что вам нужно, это дополнить геттер префиксом <code>get</code> а сеттер префиксом <code>set</code>. При этом, метод геттера не должен ожидать каких либо параметров, в то время как метод сеттера принимает один единственный параметр (новое значение для присвоения свойству). Например:</p>
<pre class="brush: js"><code>var o = {
a: 7,
get b() { return this.a + 1; },
set c(x) { this.a = x / 2; }
};</code></pre>
<p>Геттеры и сеттеры, могут быть добавлены существующему объекту в любой момент, при помощи метода <code>Object.defineProperties</code>. Первый параметр этого метода - объект, которому вы хотите присвоить геттер и сеттер. Второй параметр - это объект, имена свойств которого будут соответствовать именам создаваемых свойств, а значения - объекты определяющие геттер и сеттер создаваемых свойств. В следующем примере создаются в точности такие же геттер и сеттер, как и в примере выше:</p>
<pre class="brush: js"><code>var o = { a: 0 };
Object.defineProperties(o, {
'b': { get: function() { return this.a + 1; } },
'c': { set: function(x) { this.a = x / 2; } }
});
o.c = 10; // Запускает сеттер, который присваивает 10 / 2 (5) свойству 'a'
console.log(o.b); // Запускает геттер, который возвращает a + 1 (тоесть 6)</code></pre>
<p>То, какую из двух форм использовать для определения свойств, зависит от вашего стиля программирования и стоящей перед вами задачи. Если вы уже используете инициализатор объекта для определения прототипа, то, скорее всего, в большинстве случаев, вы воспользуетесь первой формой. Она более компактна и естественна. Однако, не редко, вторая форма является единственно возможной, в случаях, когда вы работаете с существующим объектом без доступа к его определению. Вторая форма наилучшим образом отражает динамическую природу JavaScript — но может сделать код сложным для чтения и понимания.</p>
<h2 id="Удаление_свойств">Удаление свойств</h2>
<p>Вы можете удалить свойство используя оператор <code>delete</code>. Следующий код показывает как удалить свойство.</p>
<pre class="brush: js">//Creates a new object, myobj, with two properties, a and b.
var myobj = new Object;
myobj.a = 5;
myobj.b = 12;
//Removes the a property, leaving myobj with only the b property.
delete myobj.a;
</pre>
<p>Вы также можете воспользоваться <code>delete</code> чтобы удалить глобальную переменную, если ключевое слово <code>var</code> не было использовано при ее объявлении:</p>
<pre class="brush: js">g = 17;
delete g;
</pre>
<p>Смотри <code>{{ web.link("Expressions_and_operators#delete", "delete") }}</code> чтобы получить дополнительную информацию.</p>
<h2 id="Сравнение_объектов">Сравнение объектов</h2>
<p>В JavaScript объекты имеют ссылочный тип. Два отдельных объекта никогда не будут равными, даже если они имеют равный набор свойств. Только сравнение двух ссылок на один и тот же объект вернет true.</p>
<pre class="brush: js"><code>// Две переменных ссылаются на два объекта с одинаковыми свойствами
var fruit = {name: 'apple'};
var fruitbear = {name: 'apple'};
fruit == fruitbear; // вернет false
fruit === fruitbear; // вернет false</code></pre>
<pre class="brush: js"><code>// Две переменные ссылаются на один общий объект
var fruit = {name: 'apple'};
var fruitbear = fruit; // присвоим переменной fruitbear ссылку на объект fruit
// теперь fruitbear и fruit ссылаются на один и тот же объект
fruit == fruitbear; // вернет true
fruit === fruitbear; // вернет true</code></pre>
<pre class="brush: js"><code>fruit.name = 'grape';
console.log(fruitbear); // вернет { name: "grape" } вместо { name: "apple" }</code></pre>
<p>Подробнее смотрите <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators">Операторы сравнения</a>.</p>
<h2 id="Смотрите_также">Смотрите также</h2>
<ul>
<li>Для детального изучения читайте <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Guide/Details_of_the_Object_Model">подробнее об объектной модели JavaScript</a>.</li>
<li>Для изучения классов ECMAScript 2015 (новый способ определения объектов), читайте главу <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Classes">классы JavaScript</a>.</li>
</ul>
<div>{{PreviousNext("Web/JavaScript/Guide/Keyed_collections", "Web/JavaScript/Guide/Details_of_the_Object_Model")}}</div>
|