Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «this всередині методу об'єкта». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Всередині **методу об'єкта** значення `this` вказує на **сам об'єкт**, через який цей метод **викликаний**. **Ключове:** `this` залежить не від місця оголошення функції, а від того, як вона викликана.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Коротка відповідь Всередині **методу об'єкта** значення `this` вказує на **сам об'єкт**, через який цей метод **викликаний**. --- ## Приклад ```javascript const user = { name: 'Oleh', sayHi() { console.log(this.name); } }; user.sayHi(); // "Oleh" ``` Тут: - `this` всередині `sayHi()` вказує на `user`, - тому що метод викликаний як `user.sayHi()`. --- ## Як це працює під капотом Коли виконується виклик: ```javascript obj.method() ``` JS робить дві речі: 1. Шукає `method` всередині `obj` (або його прототипів), 2. Викликає її **з прив'язкою контексту** - `this = obj` під час виклику. --- ## Якщо зберегти метод у змінну - контекст втрачається ```javascript const user = { name: 'Oleh', sayHi() { console.log(this.name); } }; const fn = user.sayHi; fn(); // undefined (або помилка в strict mode) ``` Чому? - При `fn()` метод викликається **без об'єкта**. - А отже, `this` всередині функції **більше не вказує на user**: - у **strict mode** -> `this = undefined`; - у **non-strict mode** -> `this = window` (у браузері). --- ## Як повернути правильний контекст ### Спосіб 1 - викликати через об'єкт ```javascript user.sayHi(); // працює ``` ### Спосіб 2 - використати bind() ```javascript const fn = user.sayHi.bind(user); fn(); // "Oleh" ``` `bind()` створює нову функцію з жорстко "прив'язаним" контекстом. --- ## Приклад із вкладеними об'єктами ```javascript const user = { name: 'Oleh', address: { city: 'Kyiv', getCity() { console.log(this.city); } } }; user.address.getCity(); // "Kyiv" ``` Тут `this` вказує на `address`, тому що метод був викликаний як `user.address.getCity()`. --- ## Але якщо винести функцію назовні... ```javascript const cityFunc = user.address.getCity; cityFunc(); // undefined ``` Втратили контекст - виклик без об'єкта. --- ## this не залежить від місця, де функція оголошена Лише від **того, як вона викликана**: ```javascript function show() { console.log(this); } const obj1 = { show }; const obj2 = { show }; obj1.show(); // this = obj1 obj2.show(); // this = obj2 ``` Один і той самий код функції, але `this` різний - тому що викликали через різні об'єкти. --- ## У стрілкових функціях this поводиться інакше ```javascript const user = { name: 'Oleh', sayHi: () => { console.log(this.name); } }; user.sayHi(); // undefined ``` У **стрілкових функцій немає власного** `this` - вони беруть `this` із **зовнішнього лексичного оточення** (де були оголошені). У цьому випадку - із глобальної області. Тому в методах об'єктів **не варто використовувати стрілкові функції**. --- ## Приклад, де стрілка все-таки доречна Стрілки корисні, якщо потрібно **зберегти** `this` із зовнішнього методу: ```javascript const user = { name: 'Oleh', friends: ['Bob', 'Max'], showFriends() { this.friends.forEach(friend => { console.log(`${this.name} знає ${friend}`); }); } }; user.showFriends(); // "Oleh знає Bob" // "Oleh знає Max" ``` Тут `friend =>` не створює новий `this`, тому стрілка використовує `this` із методу `showFriends()`. --- ## ПІДСУМОК | Ситуація | Що таке `this` | |---|---| | `obj.method()` | сам `obj` | | `method()` без об'єкта | `undefined` (або `window` у старому режимі) | | Стрілкова функція | `this` із зовнішньої області | | `bind(obj)` | завжди `obj`, незалежно від виклику | | `call` / `apply` | задають `this` вручну під час виклику |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.