Skip to content

Commit c050f14

Browse files
authored
1-js/09-classes/06-instanceof: Translation (#227)
1 parent 32ad38c commit c050f14

File tree

3 files changed

+72
-72
lines changed

3 files changed

+72
-72
lines changed
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
Yeah, looks strange indeed.
1+
Так, виглядає справді дивно.
22

3-
But `instanceof` does not care about the function, but rather about its `prototype`, that it matches against the prototype chain.
3+
Але `instanceof` нема діла до функції, все залежить від її властивості `prototype`, значення якої порівнюється з ланцюжком прототипів.
44

5-
And here `a.__proto__ == B.prototype`, so `instanceof` returns `true`.
5+
І тут `a.__proto__ == B.prototype`, тому `instanceof` повертає `true`.
66

7-
So, by the logic of `instanceof`, the `prototype` actually defines the type, not the constructor function.
7+
Отже, за логікою `instanceof`, властивість `prototype` насправді визначає тип, а не сама функція-конструктор.

1-js/09-classes/06-instanceof/1-strange-instanceof/task.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ importance: 5
22

33
---
44

5-
# Strange instanceof
5+
# Дивний instanceof
66

7-
In the code below, why does `instanceof` return `true`? We can easily see that `a` is not created by `B()`.
7+
Чому `instanceof` повертає `true` у коді нижче? Ми можемо легко побачити, що `a` не створюється `B()`.
88

99
```js run
1010
function A() {}
Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,62 @@
1-
# Class checking: "instanceof"
1+
# Перевірка класу: "instanceof"
22

3-
The `instanceof` operator allows to check whether an object belongs to a certain class. It also takes inheritance into account.
3+
Оператор `instanceof` дозволяє перевірити, чи належить об’єкт до певного класу. Він також враховує наслідування.
44

5-
Such a check may be necessary in many cases. For example, it can be used for building a *polymorphic* function, the one that treats arguments differently depending on their type.
5+
Така перевірка може знадобитися в багатьох випадках. Наприклад, його можна використати для створення *поліморфної* функції, яка обробляє аргументи по-різному залежно від їх типу.
66

7-
## The instanceof operator [#ref-instanceof]
7+
## Оператор instanceof [#ref-instanceof]
88

9-
The syntax is:
9+
Синтаксис такий:
1010
```js
1111
obj instanceof Class
1212
```
1313

14-
It returns `true` if `obj` belongs to the `Class` or a class inheriting from it.
14+
Він повертає `true`, якщо `obj` належить до класу `Class` або класу, який наслідується від нього.
1515

16-
For instance:
16+
Наприклад:
1717

1818
```js run
1919
class Rabbit {}
2020
let rabbit = new Rabbit();
2121

22-
// is it an object of Rabbit class?
22+
// Чи це об’єкт класу Rabbit?
2323
*!*
2424
alert( rabbit instanceof Rabbit ); // true
2525
*/!*
2626
```
2727

28-
It also works with constructor functions:
28+
Він також працює з функціями-конструкторами:
2929

3030
```js run
3131
*!*
32-
// instead of class
32+
// замість класу
3333
function Rabbit() {}
3434
*/!*
3535

3636
alert( new Rabbit() instanceof Rabbit ); // true
3737
```
3838

39-
...And with built-in classes like `Array`:
39+
...І з вбудованими класами як `Array`:
4040

4141
```js run
4242
let arr = [1, 2, 3];
4343
alert( arr instanceof Array ); // true
4444
alert( arr instanceof Object ); // true
4545
```
4646

47-
Please note that `arr` also belongs to the `Object` class. That's because `Array` prototypically inherits from `Object`.
47+
Будь ласка, зверніть увагу, що `arr` також належить до класу `Object`. Це тому, що клас `Array` прототипно наслідується від `Object`.
4848

49-
Normally, `instanceof` examines the prototype chain for the check. We can also set a custom logic in the static method `Symbol.hasInstance`.
49+
Зазвичай, `instanceof` перевіряє ланцюжок прототипів. Ми також можемо задати будь-яку спеціальну логіку в статичному методі `Symbol.hasInstance`, і замінити звичайну поведінку.
5050

51-
The algorithm of `obj instanceof Class` works roughly as follows:
51+
Алгоритм операції `obj instanceof Class` працює приблизно наступним чином:
5252

53-
1. If there's a static method `Symbol.hasInstance`, then just call it: `Class[Symbol.hasInstance](obj)`. It should return either `true` or `false`, and we're done. That's how we can customize the behavior of `instanceof`.
53+
1. Якщо є статичний метод `Symbol.hasInstance`, тоді він просто викликаєтсья: `Class[Symbol.hasInstance](obj)`. Він повинен повернути `true` або `false`, ось і все. Ось як ми можемо задати поведінку `instanceof`.
5454

55-
For example:
55+
Наприклад:
5656

5757
```js run
58-
// setup instanceOf check that assumes that
59-
// anything with canEat property is an animal
58+
// задамо перевірку instanceof таким чином,
59+
// що будь-що із властивістю canEat - це тварина
6060
class Animal {
6161
static [Symbol.hasInstance](obj) {
6262
if (obj.canEat) return true;
@@ -65,24 +65,24 @@ The algorithm of `obj instanceof Class` works roughly as follows:
6565

6666
let obj = { canEat: true };
6767

68-
alert(obj instanceof Animal); // true: Animal[Symbol.hasInstance](obj) is called
68+
alert(obj instanceof Animal); // true: Animal[Symbol.hasInstance](obj) було викликано
6969
```
7070

71-
2. Most classes do not have `Symbol.hasInstance`. In that case, the standard logic is used: `obj instanceOf Class` checks whether `Class.prototype` is equal to one of the prototypes in the `obj` prototype chain.
71+
2. Більшість класів не мають `Symbol.hasInstance`. У цьому випадку використовується стандартна логіка: `obj instanceOf Class` перевіряє чи `Class.prototype` дорівнює одному з прототипів у ланцюжку прототипів `obj`.
7272

73-
In other words, compare one after another:
73+
Іншими словами, прототипи порівнюються один за одним:
7474
```js
7575
obj.__proto__ === Class.prototype?
7676
obj.__proto__.__proto__ === Class.prototype?
7777
obj.__proto__.__proto__.__proto__ === Class.prototype?
7878
...
79-
// if any answer is true, return true
80-
// otherwise, if we reached the end of the chain, return false
79+
// Якщо будь-яке з них буде true, то instanceof одразу ж верне true.
80+
// Якщо ми досягли кінця ланцюжка - повертається false
8181
```
8282

83-
In the example above `rabbit.__proto__ === Rabbit.prototype`, so that gives the answer immediately.
83+
У наведеному вище прикладі `rabbit.__proto__ === Rabbit.prototype`, тому ми знаходимо відповідь негайно.
8484

85-
In the case of an inheritance, the match will be at the second step:
85+
У разі наслідування ми знайдемо те, що шукали, на другому кроці:
8686

8787
```js run
8888
class Animal {}
@@ -93,76 +93,76 @@ The algorithm of `obj instanceof Class` works roughly as follows:
9393
alert(rabbit instanceof Animal); // true
9494
*/!*
9595
96-
// rabbit.__proto__ === Animal.prototype (no match)
96+
// rabbit.__proto__ === Animal.prototype (немає збігу)
9797
*!*
98-
// rabbit.__proto__.__proto__ === Animal.prototype (match!)
98+
// rabbit.__proto__.__proto__ === Animal.prototype (знайшли!)
9999
*/!*
100100
```
101101

102-
Here's the illustration of what `rabbit instanceof Animal` compares with `Animal.prototype`:
102+
Ось ілюстрація того, як операція `rabbit instanceof Animal` шукає `Animal.prototype` у прототипах:
103103

104104
![](instanceof.svg)
105105

106-
By the way, there's also a method [objA.isPrototypeOf(objB)](mdn:js/object/isPrototypeOf), that returns `true` if `objA` is somewhere in the chain of prototypes for `objB`. So the test of `obj instanceof Class` can be rephrased as `Class.prototype.isPrototypeOf(obj)`.
106+
До речі, є також метод [objA.isPrototypeOf(objB)](mdn:js/object/isPrototypeOf), який повертає `true` якщо `objA` знаходиться десь у ланцюжку прототипів для `objB`. Отже, перевірку `obj instanceof Class` можна замінити на `Class.prototype.isPrototypeOf(obj)`.
107107

108-
It's funny, but the `Class` constructor itself does not participate in the check! Only the chain of prototypes and `Class.prototype` matters.
108+
Цікаво, але сам класс `Class` не бере участі в перевірці! Має значення лише ланцюжок прототипів і `Class.prototype`.
109109

110-
That can lead to interesting consequences when a `prototype` property is changed after the object is created.
110+
Це може призвести до дивних наслідків, коли властивість `prototype` було змінено після створення об’єкта.
111111

112-
Like here:
112+
Як тут:
113113

114114
```js run
115115
function Rabbit() {}
116116
let rabbit = new Rabbit();
117117
118-
// changed the prototype
118+
// Змінюємо прототип
119119
Rabbit.prototype = {};
120120
121-
// ...not a rabbit any more!
121+
// ...це більше не rabbit!
122122
*!*
123123
alert( rabbit instanceof Rabbit ); // false
124124
*/!*
125125
```
126126

127-
## Bonus: Object.prototype.toString for the type
127+
## Бонус: Object.prototype.toString для визначення типу
128128

129-
We already know that plain objects are converted to string as `[object Object]`:
129+
Ми вже знаємо, що прості об’єкти перетворюються на рядки як `[object Object]`:
130130

131131
```js run
132132
let obj = {};
133133
134134
alert(obj); // [object Object]
135-
alert(obj.toString()); // the same
135+
alert(obj.toString()); // теж саме
136136
```
137137

138-
That's their implementation of `toString`. But there's a hidden feature that makes `toString` actually much more powerful than that. We can use it as an extended `typeof` and an alternative for `instanceof`.
138+
Це їх реалізація метода `toString`. Але є прихована функція, яка робить метод `toString` набагато потужнішим. Ми можемо використовувати його як розширений `typeof` і альтернативу `instanceof`.
139139

140-
Sounds strange? Indeed. Let's demystify.
140+
Звучить дивно? Дійсно. Давайте розбиратися.
141141

142-
By [specification](https://tc39.github.io/ecma262/#sec-object.prototype.tostring), the built-in `toString` can be extracted from the object and executed in the context of any other value. And its result depends on that value.
142+
У [специфікації](https://tc39.github.io/ecma262/#sec-object.prototype.tostring), вбудований метод `toString` можна витягнути з об’єкта та викликати в контексті будь-якого іншого значення. І результат залежить від типу цього значення.
143143

144-
- For a number, it will be `[object Number]`
145-
- For a boolean, it will be `[object Boolean]`
146-
- For `null`: `[object Null]`
147-
- For `undefined`: `[object Undefined]`
148-
- For arrays: `[object Array]`
149-
- ...etc (customizable).
144+
- Для числа це буде `[object Number]`
145+
- Для логічного значення це буде `[object Boolean]`
146+
- Для `null`: `[object Null]`
147+
- Для `undefined`: `[object Undefined]`
148+
- Для масивів: `[object Array]`
149+
- ...тощо.
150150

151-
Let's demonstrate:
151+
Давайте продемонструємо:
152152

153153
```js run
154-
// copy toString method into a variable for convenience
154+
// скопіюємо метод toString у змінну для зручності
155155
let objectToString = Object.prototype.toString;
156156
157-
// what type is this?
157+
// Що це за тип?
158158
let arr = [];
159159
160160
alert( objectToString.call(arr) ); // [object *!*Array*/!*]
161161
```
162162

163-
Here we used [call](mdn:js/function/call) as described in the chapter [](info:call-apply-decorators) to execute the function `objectToString` in the context `this=arr`.
163+
Тут ми використали [call](mdn:js/function/call), як описано в розділі [](info:call-apply-decorators), щоб викликати функцію `objectToString` з контекстом `this=arr`.
164164

165-
Internally, the `toString` algorithm examines `this` and returns the corresponding result. More examples:
165+
Всередені алгоритм `toString` перевіряє `this` і повертає відповідний результат. Більше прикладів:
166166

167167
```js run
168168
let s = Object.prototype.toString;
@@ -174,9 +174,9 @@ alert( s.call(alert) ); // [object Function]
174174

175175
### Symbol.toStringTag
176176

177-
The behavior of Object `toString` can be customized using a special object property `Symbol.toStringTag`.
177+
Поведінку методу об’єкта `toString` можна налаштувати за допомогою спеціальної властивості `Symbol.toStringTag`.
178178

179-
For instance:
179+
Наприклад:
180180

181181
```js run
182182
let user = {
@@ -186,33 +186,33 @@ let user = {
186186
alert( {}.toString.call(user) ); // [object User]
187187
```
188188
189-
For most environment-specific objects, there is such a property. Here are some browser specific examples:
189+
Для більшості специфічних для середовища об’єктів така властивість є. Ось деякі приклади для браузера:
190190
191191
```js run
192-
// toStringTag for the environment-specific object and class:
192+
// toStringTag для специфічних для середовища об’єкту та класу:
193193
alert( window[Symbol.toStringTag]); // Window
194194
alert( XMLHttpRequest.prototype[Symbol.toStringTag] ); // XMLHttpRequest
195195

196196
alert( {}.toString.call(window) ); // [object Window]
197197
alert( {}.toString.call(new XMLHttpRequest()) ); // [object XMLHttpRequest]
198198
```
199199
200-
As you can see, the result is exactly `Symbol.toStringTag` (if exists), wrapped into `[object ...]`.
200+
Як бачите, результатом є саме `Symbol.toStringTag` (якщо існує), загорнутий у `[object ...]`.
201201
202-
At the end we have "typeof on steroids" that not only works for primitive data types, but also for built-in objects and even can be customized.
202+
Наприкінці ми маємо "typeof на стероїдах", який працює не тільки для примітивних типів даних, але й для вбудованих об’єктів і навіть може бути кастомізований.
203203
204-
We can use `{}.toString.call` instead of `instanceof` for built-in objects when we want to get the type as a string rather than just to check.
204+
Ми можемо використати `{}.toString.call` замість `instanceof` для вбудованих об’єктів, коли ми хочемо отримати тип у вигляді рядка, а не просто для перевірки.
205205
206-
## Summary
206+
## Підсумки
207207
208-
Let's summarize the type-checking methods that we know:
208+
Давайте підсумуємо відомі нам методи перевірки типів:
209209
210-
| | works for | returns |
210+
| | працює для | повертає |
211211
|---------------|-------------|---------------|
212-
| `typeof` | primitives | string |
213-
| `{}.toString` | primitives, built-in objects, objects with `Symbol.toStringTag` | string |
214-
| `instanceof` | objects | true/false |
212+
| `typeof` | примітивів | рядок |
213+
| `{}.toString` | примітивів, вбудованих об’єктів, об’єктів з `Symbol.toStringTag` | рядок |
214+
| `instanceof` | об’єктів | true/false |
215215
216-
As we can see, `{}.toString` is technically a "more advanced" `typeof`.
216+
Як ми бачимо, `{}.toString` технічно є "більш просунутим" `typeof`.
217217
218-
And `instanceof` operator really shines when we are working with a class hierarchy and want to check for the class taking into account inheritance.
218+
І оператор `instanceof` дійсно сяє, коли ми працюємо з ієрархією класів і хочемо перевірити клас з урахуванням наслідування.

0 commit comments

Comments
 (0)