Object.keys, values, entries by chizzzy · Pull Request #155 · javascript-tutorial/uk.javascript.info
@@ -1,86 +1,86 @@
# Object.keys, values, entries
Let's step away from the individual data structures and talk about the iterations over them. Відійдемо від окремих структур даних і поговоримо про ітерації над ними.
In the previous chapter we saw methods `map.keys()`, `map.values()`, `map.entries()`. У минулому розділі ми бачили методи `map.keys()`, `map.values()`, `map.entries()`.
These methods are generic, there is a common agreement to use them for data structures. If we ever create a data structure of our own, we should implement them too. Ці методи є загальними, існує спільна згода використовувати їх для структур даних. Якщо ми створюватимемо власну структуру даних, нам слід їх також реалізувати.
They are supported for: Вони підтримуються для:
- `Map` - `Set` - `Array`
Plain objects also support similar methods, but the syntax is a bit different. Звичайні об’єкти також підтримують подібні методи, але синтаксис дещо інший.
## Object.keys, values, entries
For plain objects, the following methods are available: Для простих об’єктів доступні наступні методи:
- [Object.keys(obj)](mdn:js/Object/keys) -- returns an array of keys. - [Object.values(obj)](mdn:js/Object/values) -- returns an array of values. - [Object.entries(obj)](mdn:js/Object/entries) -- returns an array of `[key, value]` pairs. - [Object.keys(obj)](mdn:js/Object/keys) -- повертає масив ключів. - [Object.values(obj)](mdn:js/Object/values) -- повертає масив значень. - [Object.entries(obj)](mdn:js/Object/entries) -- повертає масив пар `[ключ, значення]`.
Please note the distinctions (compared to map for example): Зверніть увагу на відмінності (порівняно з map, наприклад):
| | Map | Object | |-------------|------------------|--------------| | Call syntax | `map.keys()` | `Object.keys(obj)`, but not `obj.keys()` | | Returns | iterable | "real" Array | | Синтаксис виклику | `map.keys()` | `Object.keys(obj)`, а не `obj.keys()` | | Повертає | ітерабельний | "реальний" масив |
The first difference is that we have to call `Object.keys(obj)`, and not `obj.keys()`. Перша відмінність полягає в тому, що ми повинні викликати `Object.keys(obj)`, а не `obj.keys()`.
Why so? The main reason is flexibility. Remember, objects are a base of all complex structures in JavaScript. So we may have an object of our own like `data` that implements its own `data.values()` method. And we still can call `Object.values(data)` on it. Чому так? Основною причиною цього є гнучкість. Пам’ятайте, об’єкти є базою всіх складних структур у JavaScript. Ми можемо мати власний об’єкт, такий як `data`, який реалізує власний метод `data.values()`. І ми все ще можемо застосовувати до нього `Object.values(data)`.
The second difference is that `Object.*` methods return "real" array objects, not just an iterable. That's mainly for historical reasons. Друга відмінність полягає в тому, що `Object.*` методи повертають "реальний" масив об’єктів, а не просто ітерабельний. Це переважно з історичних причин.
For instance: Наприклад:
```js let user = { name: "John", name: "Іван", age: 30 }; ```
- `Object.keys(user) = ["name", "age"]` - `Object.values(user) = ["John", 30]` - `Object.entries(user) = [ ["name","John"], ["age",30] ]` - `Object.values(user) = ["Іван", 30]` - `Object.entries(user) = [ ["name","Іван"], ["age",30] ]`
Here's an example of using `Object.values` to loop over property values: Це приклад використання `Object.values` для перебору значень властивостей у циклі:
```js run let user = { name: "John", name: "Іван", age: 30 };
// loop over values // Перебираємо значення for (let value of Object.values(user)) { alert(value); // John, then 30 alert(value); // Іван, тоді 30 } ```
```warn header="Object.keys/values/entries ignore symbolic properties" Just like a `for..in` loop, these methods ignore properties that use `Symbol(...)` as keys. ```warn header="Object.keys/values/entries ігнорують символьні властивості" Як і цикл `for..in`, ці методи ігнорують властивості, що використовують `Symbol(...)` як ключі.
Usually that's convenient. But if we want symbolic keys too, then there's a separate method [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols) that returns an array of only symbolic keys. Also, there exist a method [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys. Зазвичай це зручно. Якщо ми хочемо враховувати символьні ключі також, то для цього існує окремий метод [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols), що повертає масив лише символьних ключів. Також існує метод [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) , що повертає *усі* ключі. ```
## Transforming objects ## Трансформація об’єктів
Objects lack many methods that exist for arrays, e.g. `map`, `filter` and others. У об’єктів немає багатьох методів, які є у масивів, наприклад `map`, `filter` та інші.
If we'd like to apply them, then we can use `Object.entries` followed by `Object.fromEntries`: Якщо б ми хотіли їх застосувати, тоді б ми використовували `Object.entries` з подальшим викликом `Object.fromEntries`:
1. Use `Object.entries(obj)` to get an array of key/value pairs from `obj`. 2. Use array methods on that array, e.g. `map`. 3. Use `Object.fromEntries(array)` on the resulting array to turn it back into an object. 1. Викликаємо `Object.entries(obj)`, щоб отримати масив пар ключ/значення з `obj`. 2. На ньому використовуємо методи масиву, наприклад `map`. 3. Використаємо `Object.fromEntries(array)` на отриманому масиві, щоб перетворити його знову на об’єкт.
For example, we have an object with prices, and would like to double them: Наприклад, у нас є об’єкт з цінами, і ми б хотіли їх подвоїти:
```js run let prices = { Expand All @@ -91,12 +91,12 @@ let prices = {
*!* let doublePrices = Object.fromEntries( // convert to array, map, and then fromEntries gives back the object // перетворити на масив, потім застосувати map, а потім fromEntries повертає об’єкт Object.entries(prices).map(([key, value]) => [key, value * 2]) ); */!*
alert(doublePrices.meat); // 8 ```
It may look difficult at first sight, but becomes easy to understand after you use it once or twice. We can make powerful chains of transforms this way. З першого погляду це може здатися важким, але стане зрозумілим після того, як ви використаєте це декілька разів. Таким чином ми можемо створювати потужні ланцюги перетворень.
# Object.keys, values, entries
Let's step away from the individual data structures and talk about the iterations over them. Відійдемо від окремих структур даних і поговоримо про ітерації над ними.
In the previous chapter we saw methods `map.keys()`, `map.values()`, `map.entries()`. У минулому розділі ми бачили методи `map.keys()`, `map.values()`, `map.entries()`.
These methods are generic, there is a common agreement to use them for data structures. If we ever create a data structure of our own, we should implement them too. Ці методи є загальними, існує спільна згода використовувати їх для структур даних. Якщо ми створюватимемо власну структуру даних, нам слід їх також реалізувати.
They are supported for: Вони підтримуються для:
- `Map` - `Set` - `Array`
Plain objects also support similar methods, but the syntax is a bit different. Звичайні об’єкти також підтримують подібні методи, але синтаксис дещо інший.
## Object.keys, values, entries
For plain objects, the following methods are available: Для простих об’єктів доступні наступні методи:
- [Object.keys(obj)](mdn:js/Object/keys) -- returns an array of keys. - [Object.values(obj)](mdn:js/Object/values) -- returns an array of values. - [Object.entries(obj)](mdn:js/Object/entries) -- returns an array of `[key, value]` pairs. - [Object.keys(obj)](mdn:js/Object/keys) -- повертає масив ключів. - [Object.values(obj)](mdn:js/Object/values) -- повертає масив значень. - [Object.entries(obj)](mdn:js/Object/entries) -- повертає масив пар `[ключ, значення]`.
Please note the distinctions (compared to map for example): Зверніть увагу на відмінності (порівняно з map, наприклад):
| | Map | Object | |-------------|------------------|--------------| | Call syntax | `map.keys()` | `Object.keys(obj)`, but not `obj.keys()` | | Returns | iterable | "real" Array | | Синтаксис виклику | `map.keys()` | `Object.keys(obj)`, а не `obj.keys()` | | Повертає | ітерабельний | "реальний" масив |
The first difference is that we have to call `Object.keys(obj)`, and not `obj.keys()`. Перша відмінність полягає в тому, що ми повинні викликати `Object.keys(obj)`, а не `obj.keys()`.
Why so? The main reason is flexibility. Remember, objects are a base of all complex structures in JavaScript. So we may have an object of our own like `data` that implements its own `data.values()` method. And we still can call `Object.values(data)` on it. Чому так? Основною причиною цього є гнучкість. Пам’ятайте, об’єкти є базою всіх складних структур у JavaScript. Ми можемо мати власний об’єкт, такий як `data`, який реалізує власний метод `data.values()`. І ми все ще можемо застосовувати до нього `Object.values(data)`.
The second difference is that `Object.*` methods return "real" array objects, not just an iterable. That's mainly for historical reasons. Друга відмінність полягає в тому, що `Object.*` методи повертають "реальний" масив об’єктів, а не просто ітерабельний. Це переважно з історичних причин.
For instance: Наприклад:
```js let user = { name: "John", name: "Іван", age: 30 }; ```
- `Object.keys(user) = ["name", "age"]` - `Object.values(user) = ["John", 30]` - `Object.entries(user) = [ ["name","John"], ["age",30] ]` - `Object.values(user) = ["Іван", 30]` - `Object.entries(user) = [ ["name","Іван"], ["age",30] ]`
Here's an example of using `Object.values` to loop over property values: Це приклад використання `Object.values` для перебору значень властивостей у циклі:
```js run let user = { name: "John", name: "Іван", age: 30 };
// loop over values // Перебираємо значення for (let value of Object.values(user)) { alert(value); // John, then 30 alert(value); // Іван, тоді 30 } ```
```warn header="Object.keys/values/entries ignore symbolic properties" Just like a `for..in` loop, these methods ignore properties that use `Symbol(...)` as keys. ```warn header="Object.keys/values/entries ігнорують символьні властивості" Як і цикл `for..in`, ці методи ігнорують властивості, що використовують `Symbol(...)` як ключі.
Usually that's convenient. But if we want symbolic keys too, then there's a separate method [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols) that returns an array of only symbolic keys. Also, there exist a method [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys. Зазвичай це зручно. Якщо ми хочемо враховувати символьні ключі також, то для цього існує окремий метод [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols), що повертає масив лише символьних ключів. Також існує метод [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) , що повертає *усі* ключі. ```
## Transforming objects ## Трансформація об’єктів
Objects lack many methods that exist for arrays, e.g. `map`, `filter` and others. У об’єктів немає багатьох методів, які є у масивів, наприклад `map`, `filter` та інші.
If we'd like to apply them, then we can use `Object.entries` followed by `Object.fromEntries`: Якщо б ми хотіли їх застосувати, тоді б ми використовували `Object.entries` з подальшим викликом `Object.fromEntries`:
1. Use `Object.entries(obj)` to get an array of key/value pairs from `obj`. 2. Use array methods on that array, e.g. `map`. 3. Use `Object.fromEntries(array)` on the resulting array to turn it back into an object. 1. Викликаємо `Object.entries(obj)`, щоб отримати масив пар ключ/значення з `obj`. 2. На ньому використовуємо методи масиву, наприклад `map`. 3. Використаємо `Object.fromEntries(array)` на отриманому масиві, щоб перетворити його знову на об’єкт.
For example, we have an object with prices, and would like to double them: Наприклад, у нас є об’єкт з цінами, і ми б хотіли їх подвоїти:
```js run let prices = { Expand All @@ -91,12 +91,12 @@ let prices = {
*!* let doublePrices = Object.fromEntries( // convert to array, map, and then fromEntries gives back the object // перетворити на масив, потім застосувати map, а потім fromEntries повертає об’єкт Object.entries(prices).map(([key, value]) => [key, value * 2]) ); */!*
alert(doublePrices.meat); // 8 ```
It may look difficult at first sight, but becomes easy to understand after you use it once or twice. We can make powerful chains of transforms this way. З першого погляду це може здатися важким, але стане зрозумілим після того, як ви використаєте це декілька разів. Таким чином ми можемо створювати потужні ланцюги перетворень.