diff --git a/1-js/99-js-misc/04-reference-type/article.md b/1-js/99-js-misc/04-reference-type/article.md index 1c0041267..5fe520860 100644 --- a/1-js/99-js-misc/04-reference-type/article.md +++ b/1-js/99-js-misc/04-reference-type/article.md @@ -1,5 +1,5 @@ -# Посилальний Тип +# Посилальний тип ```warn header="Поглиблений функціонал мови" Ця стаття охоплює складну тему, щоб краще зрозуміти певні крайні випадки. @@ -7,7 +7,7 @@ Це не є важливим. Багато досвідчених розробників живуть добре, не знаючи цього. Прочитайте, якщо ви хочете знати, як певні речі працюють під капотом. ``` -Динамічно оцінений виклик методу може втратити `this`. +Динамічно обчислений виклик методу може втратити `this`. Наприклад: @@ -22,7 +22,7 @@ user.hi(); // працює // тепер викличмо user.hi або user.bye залежно від назви *!* -(user.name == "John" ? user.hi : user.bye)(); // Помилка! +(user.name == "Іван" ? user.hi : user.bye)(); // Помилка! */!* ``` @@ -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 = { @@ -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).** Посилальний тип -- це "тип специфікації". Ми не можемо явно використовувати його, але він використовується всередині мови. @@ -87,13 +87,13 @@ 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). ## Підсумки @@ -101,8 +101,8 @@ hi(); // Помилка, тому що this -- це undefined Читання властивості, наприклад, крапкою `.` в `obj.method()` повертає не саме значення властивості, але спеціальне значення "посилального типу", яке зберігає як значення властивості, так і об’єкт, з якою він був взятий. -Це використовується для подальшого виклику методу за допомогою `()`, щоб отримати об’єкт і встановити `this` до цього. +Це використовується для подальшого виклику методу за допомогою `()`, щоб отримати об’єкт і встановити `this` перед цим. Для всіх інших операцій, посилальний тип автоматично стає значенням властивості (функцією у нашому випадку). -Вся ця механіка прихована від наших очей. Це лише важливо в тонких випадках, наприклад, коли метод отримується динамічно з об’єкта, використовуючи вираз. +Уся ця механіка прихована від наших очей. Це важливо лише в тонких випадках, наприклад, коли метод отримується динамічно з об’єкта, використовуючи вираз.