this всередині методу об'єкта
Коротка відповідь
Всередині методу об'єкта значення this вказує на сам об'єкт, через який цей метод викликаний.
Приклад
const user = {
name: 'Oleh',
sayHi() {
console.log(this.name);
}
};
user.sayHi(); // "Oleh"Тут:
thisвсерединіsayHi()вказує наuser,- тому що метод викликаний як
user.sayHi().
Як це працює під капотом
Коли виконується виклик:
obj.method()JS робить дві речі:
- Шукає
methodвсерединіobj(або його прототипів), - Викликає її з прив'язкою контексту -
this = objпід час виклику.
Якщо зберегти метод у змінну - контекст втрачається
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(у браузері).
- у strict mode ->
Як повернути правильний контекст
Спосіб 1 - викликати через об'єкт
user.sayHi(); // працюєСпосіб 2 - використати bind()
const fn = user.sayHi.bind(user);
fn(); // "Oleh"bind() створює нову функцію з жорстко "прив'язаним" контекстом.
Приклад із вкладеними об'єктами
const user = {
name: 'Oleh',
address: {
city: 'Kyiv',
getCity() {
console.log(this.city);
}
}
};
user.address.getCity(); // "Kyiv"Тут this вказує на address,
тому що метод був викликаний як user.address.getCity().
Але якщо винести функцію назовні...
const cityFunc = user.address.getCity;
cityFunc(); // undefinedВтратили контекст - виклик без об'єкта.
this не залежить від місця, де функція оголошена
Лише від того, як вона викликана:
function show() {
console.log(this);
}
const obj1 = { show };
const obj2 = { show };
obj1.show(); // this = obj1
obj2.show(); // this = obj2Один і той самий код функції,
але this різний - тому що викликали через різні об'єкти.
У стрілкових функціях this поводиться інакше
const user = {
name: 'Oleh',
sayHi: () => {
console.log(this.name);
}
};
user.sayHi(); // undefinedУ стрілкових функцій немає власного this -
вони беруть this із зовнішнього лексичного оточення (де були оголошені).
У цьому випадку - із глобальної області.
Тому в методах об'єктів не варто використовувати стрілкові функції.
Приклад, де стрілка все-таки доречна
Стрілки корисні, якщо потрібно зберегти this із зовнішнього методу:
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 вручну під час виклику |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.