Skip to content

Commit b3f6bad

Browse files
Property getters and setters (#206)
Co-authored-by: Ivan D <[email protected]>
1 parent b9df5e5 commit b3f6bad

File tree

1 file changed

+66
-66
lines changed
  • 1-js/07-object-properties/02-property-accessors

1 file changed

+66
-66
lines changed
Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,45 @@
11

2-
# Property getters and setters
2+
# Гетери і сетери властивостей
33

4-
There are two kinds of object properties.
4+
Є два види властивостей об’єкта.
55

6-
The first kind is *data properties*. We already know how to work with them. All properties that we've been using until now were data properties.
6+
Перший вид *властивості даних (data properties)*. Ми вже знаємо, як працювати з ними. Всі властивості, які ми використовували дотепер, були властивостями даних.
77

8-
The second type of properties is something new. It's *accessor properties*. They are essentially functions that execute on getting and setting a value, but look like regular properties to an external code.
8+
Другий вид властивостей -- це щось нове. Це *властивості аксесорів*. Вони по суті функції, які виконуються при отриманні та встановленні значення, але виглядають як звичайні властивості в зовнішньому коді.
99

10-
## Getters and setters
10+
## Гетери та сетери
1111

12-
Accessor properties are represented by "getter" and "setter" methods. In an object literal they are denoted by `get` and `set`:
12+
Властивості аксесорів представлені методами "гетер" та "сетер". У об’єкті вони буквально позначаються як `get` і `set`:
1313

1414
```js
1515
let obj = {
1616
*!*get propName()*/!* {
17-
// getter, the code executed on getting obj.propName
17+
// гетер, код виконано під час отримання obj.propName
1818
},
1919

2020
*!*set propName(value)*/!* {
21-
// setter, the code executed on setting obj.propName = value
21+
// сетер, код виконано під час встановлення obj.propName = value
2222
}
2323
};
2424
```
2525

26-
The getter works when `obj.propName` is read, the setter -- when it is assigned.
26+
Гетер працює, коли `obj.propName` зчитується, сетер -- коли він призначається.
2727

28-
For instance, we have a `user` object with `name` and `surname`:
28+
Наприклад, у нас є об’єкт `user` з `name` і `surname`:
2929

3030
```js
3131
let user = {
32-
name: "John",
33-
surname: "Smith"
32+
name: "Іван",
33+
surname: "Іванов"
3434
};
3535
```
3636

37-
Now we want to add a `fullName` property, that should be `"John Smith"`. Of course, we don't want to copy-paste existing information, so we can implement it as an accessor:
37+
Тепер ми хочемо додати властивість `fullName`, яка повинна бути `"John Smith"`. Звичайно, ми не хочемо копіювати інформацію, що існує, тому ми можемо реалізувати її як аксесор:
3838

3939
```js run
4040
let user = {
41-
name: "John",
42-
surname: "Smith",
41+
name: "Іван",
42+
surname: "Іванов",
4343

4444
*!*
4545
get fullName() {
@@ -49,13 +49,13 @@ let user = {
4949
};
5050

5151
*!*
52-
alert(user.fullName); // John Smith
52+
alert(user.fullName); // Іван Іванов
5353
*/!*
5454
```
5555

56-
From the outside, an accessor property looks like a regular one. That's the idea of accessor properties. We don't *call* `user.fullName` as a function, we *read* it normally: the getter runs behind the scenes.
56+
Ззовні аксесор виглядає як звичайна властивість. В цьому і є ідея аксесорів властивостей. Ми не *викликаємо* `user.fullname` як функцію, ми *читаємо* її як звичайну властивість: гетер виконає свою роботу за кулісами.
5757

58-
As of now, `fullName` has only a getter. If we attempt to assign `user.fullName=`, there will be an error:
58+
Зараз `fullname` має тільки гетер. Якщо ми намагаємося присвоїти `user.fullName=`, буде помилка:
5959

6060
```js run
6161
let user = {
@@ -65,16 +65,16 @@ let user = {
6565
};
6666

6767
*!*
68-
user.fullName = "Test"; // Error (property has only a getter)
68+
user.fullName = "Test"; // Помилка (властивість має лише гетер)
6969
*/!*
7070
```
7171

72-
Let's fix it by adding a setter for `user.fullName`:
72+
Виправимо це, додавши сетер для `user.fullName`:
7373

7474
```js run
7575
let user = {
76-
name: "John",
77-
surname: "Smith",
76+
name: "Іван",
77+
surname: "Іванов",
7878

7979
get fullName() {
8080
return `${this.name} ${this.surname}`;
@@ -87,34 +87,34 @@ let user = {
8787
*/!*
8888
};
8989

90-
// set fullName is executed with the given value.
91-
user.fullName = "Alice Cooper";
90+
// виконується встановлення повного ім’я із заданим значенням.
91+
user.fullName = "Аліса Бондар";
9292

93-
alert(user.name); // Alice
94-
alert(user.surname); // Cooper
93+
alert(user.name); // Аліса
94+
alert(user.surname); // Бондар
9595
```
9696

97-
As the result, we have a "virtual" property `fullName`. It is readable and writable.
97+
Як результат, у нас є "віртуальна" властивість `fullName`. Вона читається і записується.
9898

99-
## Accessor descriptors
99+
## Дескриптори аксесорів
100100

101-
Descriptors for accessor properties are different from those for data properties.
101+
Дескриптори для аксесорів властивостей відрізняються від дескрипторів для властивостей даних.
102102

103-
For accessor properties, there is no `value` or `writable`, but instead there are `get` and `set` functions.
103+
Для аксесорів властивостей немає `value` або `writable`, але замість цього є `get` і `set` функції.
104104

105-
That is, an accessor descriptor may have:
105+
Тобто, дескриптор аксесорів може мати:
106106

107-
- **`get`** -- a function without arguments, that works when a property is read,
108-
- **`set`** -- a function with one argument, that is called when the property is set,
109-
- **`enumerable`** -- same as for data properties,
110-
- **`configurable`** -- same as for data properties.
107+
- **`get`** -- функція без аргументів, що працює, коли читається властивість,
108+
- **`set`** -- функція з одним аргументом, що викликається, коли встановлюється властивість,
109+
- **`enumerable`** -- теж саме, що і для властивостей даних,
110+
- **`configurable`** -- теж саме, що і для властивостей даних.
111111

112-
For instance, to create an accessor `fullName` with `defineProperty`, we can pass a descriptor with `get` and `set`:
112+
Наприклад, щоб створити аксесори `fullName` з `defineProperty`, ми можемо передати дескриптор з `get` і `set`:
113113

114114
```js run
115115
let user = {
116-
name: "John",
117-
surname: "Smith"
116+
name: "Іван",
117+
surname: "Іванов"
118118
};
119119

120120
*!*
@@ -129,18 +129,18 @@ Object.defineProperty(user, 'fullName', {
129129
*/!*
130130
});
131131

132-
alert(user.fullName); // John Smith
132+
alert(user.fullName); // Іван Іванов
133133

134134
for(let key in user) alert(key); // name, surname
135135
```
136136

137-
Please note that a property can be either an accessor (has `get/set` methods) or a data property (has a `value`), not both.
137+
Будь ласка, зверніть увагу, що властивість може бути або аксесором (має `get/set` методи) або властивістю даних (має `value`), але не обома одразу.
138138

139-
If we try to supply both `get` and `value` in the same descriptor, there will be an error:
139+
Якщо ми спробуємо передати як `get` і `value` у тому ж дескрипторі, то буде помилка:
140140

141141
```js run
142142
*!*
143-
// Error: Invalid property descriptor.
143+
// Помилка: Неправильний дескриптор властивостей.
144144
*/!*
145145
Object.defineProperty({}, 'prop', {
146146
get() {
@@ -151,11 +151,11 @@ Object.defineProperty({}, 'prop', {
151151
});
152152
```
153153

154-
## Smarter getters/setters
154+
## Розумні гетери/сетери
155155

156-
Getters/setters can be used as wrappers over "real" property values to gain more control over operations with them.
156+
Гетери/сетери можуть бути використані як обгортки над "реальними" значеннями властивостей, щоб отримати більше контролю над операціями з ними.
157157

158-
For instance, if we want to forbid too short names for `user`, we can have a setter `name` and keep the value in a separate property `_name`:
158+
Наприклад, якщо ми хочемо заборонити занадто короткі імена для `user`, ми можемо мати сетер `name` і зберігати значення в окремій властивості `_name`:
159159

160160
```js run
161161
let user = {
@@ -165,67 +165,67 @@ let user = {
165165

166166
set name(value) {
167167
if (value.length < 4) {
168-
alert("Name is too short, need at least 4 characters");
168+
alert("Ім’я занадто коротке, потрібно щонайменше 4 символи");
169169
return;
170170
}
171171
this._name = value;
172172
}
173173
};
174174

175-
user.name = "Pete";
176-
alert(user.name); // Pete
175+
user.name = "Петро";
176+
alert(user.name); // Петро
177177

178-
user.name = ""; // Name is too short...
178+
user.name = ""; // Ім’я занадто коротке...
179179
```
180180

181-
So, the name is stored in `_name` property, and the access is done via getter and setter.
181+
Отже, ім’я зберігається у властивості `_name`, а доступ виконується за допомогою гетера та сетера.
182182

183-
Technically, external code is able to access the name directly by using `user._name`. But there is a widely known convention that properties starting with an underscore `"_"` are internal and should not be touched from outside the object.
183+
Технічно зовнішній код може мати доступ до ім’я безпосередньо за допомогою `user._name`. Але існує широко відома конвенція, що властивості, що починаються з підкреслення `"_"`, є внутрішніми і не повинні використовуватися ззовні об’єкта.
184184

185185

186-
## Using for compatibility
186+
## Використання для сумісності
187187

188-
One of the great uses of accessors is that they allow to take control over a "regular" data property at any moment by replacing it with a getter and a setter and tweak its behavior.
188+
Одним з чудових прикладів використання аксесорів полягає у тому, що вони дозволяють контролювати "звичайну" властивість даних в будь-який момент, замінюючи її гетером і сетером і налаштовуючи її поведінку.
189189

190-
Imagine we started implementing user objects using data properties `name` and `age`:
190+
Уявіть, що ми почали реалізувати об’єкти користувача за допомогою властивостей даних `name` та `age`:
191191

192192
```js
193193
function User(name, age) {
194194
this.name = name;
195195
this.age = age;
196196
}
197197

198-
let john = new User("John", 25);
198+
let john = new User("Іван", 25);
199199

200200
alert( john.age ); // 25
201201
```
202202

203-
...But sooner or later, things may change. Instead of `age` we may decide to store `birthday`, because it's more precise and convenient:
203+
...Але рано чи пізно, речі можуть змінюватися. Замість `age` ми можемо вирішити зберігати `birthday`, тому що це точніше і зручніше:
204204

205205
```js
206206
function User(name, birthday) {
207207
this.name = name;
208208
this.birthday = birthday;
209209
}
210210

211-
let john = new User("John", new Date(1992, 6, 1));
211+
let john = new User("Іван", new Date(1992, 6, 1));
212212
```
213213

214-
Now what to do with the old code that still uses `age` property?
214+
Тепер, що робити зі старим кодом, який все ще використовує властивість `age`?
215215

216-
We can try to find all such places and fix them, but that takes time and can be hard to do if that code is used by many other people. And besides, `age` is a nice thing to have in `user`, right?
216+
Ми можемо спробувати знайти всі такі місця та виправити їх, але це вимагає часу, і це може бути важко зробити, якщо цей код використовується багатьма іншими людьми. І, крім того, `age` -- це гарна властивість для `user`, правильно?
217217

218-
Let's keep it.
218+
Залишмо його.
219219

220-
Adding a getter for `age` solves the problem:
220+
Додавання гетера для `age` розв’язує проблему:
221221

222222
```js run no-beautify
223223
function User(name, birthday) {
224224
this.name = name;
225225
this.birthday = birthday;
226226

227227
*!*
228-
// age is calculated from the current date and birthday
228+
// вік розраховується з поточної дати та дня народження
229229
Object.defineProperty(this, "age", {
230230
get() {
231231
let todayYear = new Date().getFullYear();
@@ -235,10 +235,10 @@ function User(name, birthday) {
235235
*/!*
236236
}
237237

238-
let john = new User("John", new Date(1992, 6, 1));
238+
let john = new User("Іван", new Date(1992, 6, 1));
239239

240-
alert( john.birthday ); // birthday is available
241-
alert( john.age ); // ...as well as the age
240+
alert( john.birthday ); // день народження доступний
241+
alert( john.age ); // ...так само, як і вік
242242
```
243243

244-
Now the old code works too and we've got a nice additional property.
244+
Тепер старий код теж працює, і у нас є гарна додаткова властивість.

0 commit comments

Comments
 (0)