Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix symbol (chapter 02-04-08) #698

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions 1-js/04-object-basics/08-symbol/article.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ alert(id1 == id2); // false
*/!*
```

Якщо ви знайомі з Ruby чи іншою мовою програмування, яка також має «символи» - будь ласка, не думайте що це те саме. Символи в JavaScript мають свої особливості.
Якщо ви знайомі з Ruby чи іншою мовою програмування, яка також має «символи» - будь ласка, не думайте, що це те саме. Символи в JavaScript мають свої особливості.

Отже, підсумовуючи, символи -- це "примітивні унікальні значення" з додатковим описом. Подивімось, де ми можемо їх використовувати.

Expand Down Expand Up @@ -172,9 +172,9 @@ for (let key in user) alert(key); // name, age (дані ключі не є си
alert( "Прямий доступ: " + user[id] ); // Прямий доступ: 123
```

[Object.keys(user)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) також ігнорує їх. Це частина загального принципу "приховування символьних властивостей". Якщо інший скрипт або бібліотека спробує перебрати наш об’єкт за допомогою циклу, він несподівано не отримає доступ до символьних властивостей.
[Object.keys(user)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) також ігнорує їх. Це частина загального принципу "приховування символьних властивостей". Якщо інший скрипт або бібліотека спробує перебрати наш об’єкт за допомогою циклу, то ситуації коли він несподівано отримає доступ до символьних властивостей не станеться.

А ось, [Object.assign](mdn:js/Object/assign) копіює властивості рядка та символу:
А ось, [Object.assign](mdn:js/Object/assign) скопіює і властивості підписані рядком, і властивості підписані символом:

```js run
let id = Symbol("id");
Expand All @@ -187,22 +187,22 @@ let clone = Object.assign({}, user);
alert( clone[id] ); // 123
```

Тут немає парадокса. Саме так задумано. Ідея полягає в тому, що коли ми клонуємо об’єкт або об’єднуємо об’єкти, ми зазвичай хочемо скопіювати *всі* властивості (включаючи властивості з ключами-символами, як, наприклад `id` з прикладу вище).
Тут немає парадоксу. Саме так задумано. Ідея полягає в тому, що коли ми клонуємо об’єкт або об’єднуємо об’єкти, ми зазвичай хочемо скопіювати *всі* властивості (включаючи властивості з ключами-символами, як, наприклад `id` з прикладу вище).

## Глобальні символи

Як ми вже бачили, зазвичай усі символи унікальні, навіть якщо вони мають однакову назву. Але іноді ми хочемо, щоб однойменні символи були однаковими сутностями. Наприклад, різні частини нашого додатка хочуть отримати доступ до символу `"id"`, що означає абсолютно однакову властивість.

Для цього існує *глобальний реєстр символів*. Ми можемо створити в ньому символи та отримати до них доступ пізніше, і це гарантує, що повторні звернення з тим самим іменем нам повернуть абсолютно однаковий символ.

Для того, щоб знайти (створити, якщо його немає) символ у реєстрі, використовуйте `Symbol.for(key)`.
Для того, щоб знайти (або створити, якщо його немає) символ у реєстрі, використовуйте `Symbol.for(key)`.

Цей виклик перевіряє глобальний реєстр, і якщо є символ з іменем `key`, тоді повертає його, інакше створює новий символ `Symbol(key)` і зберігає його в реєстрі за вказаним `key`.

Наприклад:

```js run
// шукаємо в глобального реєстрі
// шукаємо в глобальному реєстрі
let id = Symbol.for("id"); // якщо такого символу немає, він буде створений

// шукаємо знову, але присвоюємо в іншу змінну (можливо в іншій частині коду)
Expand All @@ -222,7 +222,7 @@ alert( id === idAgain ); // true

### Symbol.keyFor

Для глобальних символів, не тільки `Symbol.for(key)` повертає символ за іменем, також існує протилежний метод: `Symbol.keyFor(sym)`, який працює навпаки: приймає глобальний символ і повертає його ім’я.
Ми побачили, що для глобальних символів `Symbol.for(key)` повертає символ, якому належить вказане ім'я `key`. Якщо ми хочемо зробити зворотнє, тобто якщо ми хочемо знайти ім'я, яке належить символу `sym` - ми можемо використати `Symbol.keyFor(sym)`:

Наприклад:

Expand All @@ -236,9 +236,9 @@ alert( Symbol.keyFor(sym) ); // name
alert( Symbol.keyFor(sym2) ); // id
```

`Symbol.keyFor` внутрішньо використовує глобальний реєстр символів для пошуку ключа символу. Тож це не працює для не глобальних символів. Якщо символ не глобальний, він не зможе його знайти та поверне нам `undefined`.
`Symbol.keyFor` внутрішньо використовує глобальний реєстр символів для пошуку ключа символу. Тож це не працює для НЕ глобальних символів. Якщо символ не глобальний, `Symbol.keyFor` не зможе його знайти та поверне нам `undefined`.

Проте, будь-які символи мають властивість `description`.
Тим не менш, всі символи мають властивість `description`.

Наприклад:

Expand All @@ -264,7 +264,7 @@ alert( localSymbol.description ); // name
- `Symbol.toPrimitive`
- ...та інші.

До прикладу, `Symbol.toPrimitive` дозволяє описати правила для об’єкта до примітивного перетворення. Ми побачимо його використання дуже скоро.
До прикладу, `Symbol.toPrimitive` дозволяє описати перетворення об’єкта в примітив. Ми побачимо його використання дуже скоро.

З іншими системними символами познайомимось ближче, коли ми будемо вивчати відповідні мовні особливості.

Expand All @@ -274,7 +274,7 @@ alert( localSymbol.description ); // name

Символ створюється за допомогою виклику `Symbol()` з необов’язковим описом (ім’я).

Символи -- завжди унікальні, навіть якщо вони мають однакову назву. Якщо ми хочемо, щоб однойменні символи були рівними за значенням, тоді слід використовувати глобальний реєстр: `Symbol.for(key)` повертає (створює за потреби) глобальний символ з ім’ям `key`. Декілька викликів `Symbol.for` з тією ж `key` повертає той самий символ.
Символи завжди унікальні, навіть якщо вони мають однакову назву. Якщо ми хочемо, щоб однаково названі символи були рівними за значенням, тоді слід використовувати глобальний реєстр: `Symbol.for(key)` повертає (або за потреби створює) глобальний символ з ім’ям `key`. Декілька викликів `Symbol.for` з тією ж `key` повертає той самий символ.

Символи мають два основних варіанти використання:

Expand Down