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

Fixing typos in Reference Type article #676

Merged
merged 2 commits into from
Jan 4, 2025
Merged
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
32 changes: 16 additions & 16 deletions 1-js/99-js-misc/04-reference-type/article.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

# Посилальний Тип
# Посилальний тип

```warn header="Поглиблений функціонал мови"
Ця стаття охоплює складну тему, щоб краще зрозуміти певні крайні випадки.

Це не є важливим. Багато досвідчених розробників живуть добре, не знаючи цього. Прочитайте, якщо ви хочете знати, як певні речі працюють під капотом.
```

Динамічно оцінений виклик методу може втратити `this`.
Динамічно обчислений виклик методу може втратити `this`.

Наприклад:

Expand All @@ -22,7 +22,7 @@ user.hi(); // працює

// тепер викличмо user.hi або user.bye залежно від назви
*!*
(user.name == "John" ? user.hi : user.bye)(); // Помилка!
(user.name == "Іван" ? user.hi : user.bye)(); // Помилка!
*/!*
```

Expand All @@ -37,23 +37,23 @@ user.hi(); // працює
user.hi();
```

Це ні (динамічно оцінений метод):
Це ні (динамічно обчислений метод):
```js
(user.name == "John" ? user.hi : user.bye)(); // Помилка!
(user.name == "Іван" ? user.hi : user.bye)(); // Помилка!
```

Чому? Якщо ми хочемо зрозуміти, чому це трапляється, загляньмо під капот, як працює виклик `obj.method()`.

## Пояснення Посилального Типу
## Пояснення Посилального типу

Дивлячись уважно, ми можемо помітити дві операції в інструкції `obj.method()`:

1. По-перше, крапка `'.'` витягує властивість `obj.method`.
2. Потім дужки `()` виконуйте її.
2. Потім дужки `()` виконують її.

Отже, як інформація про `this` передається з першої частини до другої?
Але як інформація про `this` передається з першої частини до другої?

Якщо ми поставимо ці операції на окремі рядки, то `this` напевно буде втрачено:
Якщо ми поставимо ці операції на окремі рядки, то `this` буде втрачено:

```js run
let user = {
Expand All @@ -64,13 +64,13 @@ let user = {
*!*
// розділимо отримання та виклик методу на два рядки
let hi = user.hi;
hi(); // Помилка, тому що this -- це undefined
hi(); // Помилка, тому що this - це undefined
*/!*
```

Тут `hi = user.hi` поміщає функцію в змінну, а потім на останньому рядку, ця змінна повністю автономна, і тому не має `this`.
Тут `hi = user.hi` поміщає функцію в змінну, а на наступному рядку, ця змінна повністю автономна, і тому не має `this`.

**Щоб зробити виклик `user.hi()` робочим, JavaScript використовує трюк -- крапка `'.'` повертає не функцію, а значення спеціального [посилальний типу](https://tc39.github.io/ecma262/#sec-reference-specification-type).**
**Щоб зробити виклик `user.hi()` робочим, JavaScript використовує трюк -- крапка `'.'` повертає не функцію, а значення спеціального [посилального типу](https://tc39.github.io/ecma262/#sec-reference-specification-type).**

Посилальний тип -- це "тип специфікації". Ми не можемо явно використовувати його, але він використовується всередині мови.

Expand All @@ -87,22 +87,22 @@ hi(); // Помилка, тому що this -- це undefined
(user, "hi", true)
```

Коли дужки `()` викликаються з посилальним типом, вони отримують повну інформацію про об’єкт та його метод, і можуть встановити правильний `this` (`user` у даному випадку).
Коли дужки `()` викликаються з посилальним типом, вони отримують повну інформацію про об’єкт та його метод, і можуть встановити правильний `this` (`user` у нашому випадку).

Посилальний тип -- це особливий "посередницький" внутрішній тип, який використовується з метою передачі інформації від крапки `.` до дужок виклику `()`.

Будь-яка інша операція, наприклад присвоєння `hi = user.hi` в цілому відкидає посилальний тип та приймає значення `user.hi` (функції) і передає його. Отже, будь-яка подальша операція "втрачає" `this`.

Отже, як результат, значення `this` передається правильно тільки тоді, якщо функція викликається безпосередньо за допомогою крапки `obj.method()` або синтаксису квадратних дужок `obj['method']()` (вони роблять одне й те ж саме). Існують різні способи розв’язання цієї проблеми, як [func.bind()](/bind#solution-2-bind).
Отже, як результат, значення `this` передається правильно тільки тоді, коли функція викликається безпосередньо за допомогою крапки `obj.method()` або синтаксису квадратних дужок `obj['method']()` (вони роблять одне й те ж саме). Існують різні способи розв’язання цієї проблеми, наприклад [func.bind()](/bind#solution-2-bind).

## Підсумки

Посилальний тип -- це внутрішній тип мови.

Читання властивості, наприклад, крапкою `.` в `obj.method()` повертає не саме значення властивості, але спеціальне значення "посилального типу", яке зберігає як значення властивості, так і об’єкт, з якою він був взятий.

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

Для всіх інших операцій, посилальний тип автоматично стає значенням властивості (функцією у нашому випадку).

Вся ця механіка прихована від наших очей. Це лише важливо в тонких випадках, наприклад, коли метод отримується динамічно з об’єкта, використовуючи вираз.
Уся ця механіка прихована від наших очей. Це важливо лише в тонких випадках, наприклад, коли метод отримується динамічно з об’єкта, використовуючи вираз.