aboutsummaryrefslogtreecommitdiff
path: root/files/uk/web/javascript/reference/functions/get/index.html
blob: 00b002aad063623fa1ea33be0a742b785d7eef5a (plain)
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
---
title: гетер
slug: Web/JavaScript/Reference/Functions/get
tags:
  - ECMAScript 2015
  - ECMAScript 5
  - JavaScript
  - функції
translation_of: Web/JavaScript/Reference/Functions/get
---
<div>{{jsSidebar("Functions")}}</div>

<p>Синтаксис <strong><code>get</code></strong> прив'язує властивість об'єкта до функції, яка викликатиметься під час звернення до властивості.</p>

<div>{{EmbedInteractiveExample("pages/js/functions-getter.html")}}</div>



<h2 id="Синтаксис">Синтаксис</h2>

<pre class="syntaxbox notranslate">{get <var>prop</var>() { ... } }
{get [<var>expression</var>]() { ... } }</pre>

<h3 id="Параметри">Параметри</h3>

<dl>
 <dt><code><var>prop</var></code></dt>
 <dd>Ім'я властивості, яка прив'язується до наданої функції.</dd>
 <dt><code><var>expression</var></code></dt>
 <dd>Починаючи з ECMAScript 2015, ви також можете використовувати вираз для обчислюваного імені властивості, яка прив'язується до наданої функції.</dd>
</dl>

<h2 id="Опис">Опис</h2>

<p>Іноді потрібно надати доступ до властивості, яка повертає динамічно обчислюване значення, або ви можете захотіти відобразити статус внутрішньої змінної без потреби використовувати явні виклики методів. У JavaScript це можна здійснити використанням <em>гетера</em>.</p>

<p>Змінна не може одночасно мати прив'язаний гетер та містити значення, але <em>можливо</em> використати гетер в поєднанні з сетером, щоб створити свого роду псевдовластивість.</p>

<p>Пам'ятайте наступне, працюючи з синтаксисом <code>get</code>:</p>

<ul>
 <li>Він може мати ідентифікатор, який є або числом, або рядком;</li>
 <li>Він повинен мати рівно нуль параметрів (дивіться більше інформації у статті <a class="external" href="http://whereswalden.com/2010/08/22/incompatible-es5-change-literal-getter-and-setter-functions-must-now-have-exactly-zero-or-one-arguments/" rel="external nofollow">Несумісна зміна <abbr title="ECMAScript 5th edition">ES5</abbr>: літеральні функції гетерів та сетерів тепер повинні мати рівно нуль аргументів та один аргумент</a>);</li>
 <li>Він не повинен з'являтись у об'єктному літералі з іншим гетером чи введеними даними для тієї ж властивості(<code>{ get x() { }, get x() { } }</code> та <code>{ x: ..., get x() { } }</code> заборонені).</li>
</ul>

<h2 id="Приклади">Приклади</h2>

<h3 id="Визначення_гетерів_на_нових_обєктах_у_обєктних_ініціалізаторах">Визначення гетерів на нових об'єктах у об'єктних ініціалізаторах</h3>

<p>Це створить псевдовластивість <code>latest</code> для об'єкта <code>obj</code>, яка повертатиме останній елемент масиву у <code>log</code>.</p>

<pre class="brush: js notranslate">const obj = {
  log: ['приклад','тест'],
  get latest() {
    if (this.log.length === 0) return undefined;
    return this.log[this.log.length - 1];
  }
}
console.log(obj.latest); // "тест"
</pre>

<p>Зауважте, що спроба присвоїти значення <code>latest</code> не змінить її.</p>

<h3 id="Видалення_гетера_оператором_delete">Видалення гетера оператором <code>delete</code></h3>

<p>Якщо вам потрібно прибрати гетер, ви можете його просто {{jsxref("Operators/delete", "видалити")}}:</p>

<pre class="brush: js notranslate">delete <var>obj</var>.latest;
</pre>

<h3 id="Визначення_гетера_на_існуючому_обєкті_за_допомогою_defineProperty">Визначення гетера на існуючому об'єкті за допомогою <code>defineProperty</code></h3>

<p>Щоб додати гетер до існуючого об'єкта пізніше в будь-який момент, використовуйте {{jsxref("Object.defineProperty()")}}.</p>

<pre class="brush: js notranslate">const o = {a: 0};

Object.defineProperty(o, 'b', { get: function() { return this.a + 1; } });

console.log(o.b) // Запускає гетер, який вертає a + 1 (тобто 1)</pre>

<h3 id="Використання_обчислюваного_імені_властивості">Використання обчислюваного імені властивості</h3>

<pre class="brush: js notranslate">const expr = 'foo';

const obj = {
  get [expr]() { return 'bar'; }
};

console.log(obj.foo); // "bar"</pre>

<h3 id="Розумні_самопереписувані_ліниві_гетери">Розумні / самопереписувані / ліниві гетери</h3>

<p>Гетери дають можливість <em>визначити</em> властивість об'єкта, але вони не <em>обчислюють</em> значення властивості до звернення. Гетер відкладає вартість обчислення значення, доки значення не знадобиться. Якщо воно ніколи не знадобиться, ви ніколи за це не заплатите.</p>

<p>Додаткова техніка оптимізації, що полягає у відкладені обчислення значення властивості та кешуванні її для пізнішого звернення, створює <strong>розумні (або "<a href="https://uk.wikipedia.org/wiki/%D0%9C%D0%B5%D0%BC%D0%BE%D1%96%D0%B7%D0%B0%D1%86%D1%96%D1%8F">мемоізовані</a>") гетери</strong>. Значення обчислюється під час першого виклику гетера, після чого кешується, а отже, наступні виклики повертають кешоване значення, не переобчислюючи його. Це неймовірно корисно у наступних ситуаціях:</p>

<ul>
 <li>Якщо обчислення значення властивості є дорогим (витрачає багато оперативної пам'яті чи часу процесора, створює потоки виконавців, отримує файл, і т.д.).</li>
 <li>Якщо значення не потрібне вам просто зараз. Воно використовуватиметься пізніше, або в певних випадках не використовуватиметься взагалі.</li>
 <li>Якщо воно використовується, до нього відбувається декілька звернень, і немає потреби його переобчислювати, значення ніколи не змінюється і не потребує переобчислення.</li>
</ul>

<div class="note">
<p>Це означає, що не варто писати лінивий гетер для властивості, чиє значення ви плануєте змінювати, бо, якщо гетер лінивий, він не буде його переобчислювати.</p>

<p>Зауважте, що гетери не є ані “лінивими”, ані “мемоізованими” від природи; ви маєте реалізувати цю техніку, якщо вам потрібна така поведінка.</p>
</div>

<p>У наступному прикладі об'єкт має гетер як особисту властивість. Під час отримання властивості вона видаляється з об'єкта та повторно додається, але цього разу неявно, як властивість-значення. Наприкінці повертається значення.</p>

<pre class="brush: js notranslate">get notifier() {
  delete this.notifier;
  return this.notifier = document.getElementById('bookmarked-notification-anchor');
},</pre>

<p>Для коду Firefox, дивіться також модуль <code>XPCOMUtils.jsm</code>, який визначає функцію <code><a href="/uk/docs/Mozilla/JavaScript_code_modules/XPCOMUtils.jsm#defineLazyGetter()">defineLazyGetter()</a></code>.</p>

<h3 id="get_проти_defineProperty"><code>get</code> проти <code>defineProperty</code></h3>

<p>Хоча ключове слово <code>get</code> та метод {{jsxref("Object.defineProperty()")}} дають схожі результати, існує тонка різниця між ними при використанні з {{jsxref("classes", "класами")}}.</p>

<p>При використанні <code>get</code>, властивість буде визначена на прототипі екземпляру, в той час як {{jsxref("Object.defineProperty()")}} визначає властивість на екземплярі, до якого застосовується.</p>

<pre class="brush: js notranslate">class Example {
  get hello() {
    return 'привіт';
  }
}

const obj = new Example();
console.log(obj.hello);
// "привіт"

console.log(Object.getOwnPropertyDescriptor(obj, 'hello'));
// undefined

console.log(
  Object.getOwnPropertyDescriptor(
    Object.getPrototypeOf(obj), 'hello'
  )
);
// { configurable: true, enumerable: false, get: function get hello() { return 'привіт'; }, set: undefined }</pre>

<h2 id="Специфікації">Специфікації</h2>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Специфікації</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}</td>
  </tr>
 </tbody>
</table>

<h2 id="Сумісність_з_веб-переглядачами">Сумісність з веб-переглядачами</h2>



<p>{{Compat("javascript.functions.get")}}</p>

<h2 id="Див._також">Див. також</h2>

<ul>
 <li><a href="/uk/docs/Web/JavaScript/Reference/Functions/set">сетер</a></li>
 <li>{{jsxref("Operators/delete", "delete")}}</li>
 <li>{{jsxref("Object.defineProperty()")}}</li>
 <li>{{jsxref("Object.__defineGetter__", "__defineGetter__")}}</li>
 <li>{{jsxref("Object.__defineSetter__", "__defineSetter__")}}</li>
 <li><a href="/uk/docs/Web/JavaScript/Guide/Working_with_Objects#Визначення_гетерів_та_сетерів">Визначення гетерів та сетерів</a> у посібнику JavaScript</li>
</ul>