Пошук уроків, статей та іншого контенту
Навчитеся читати контекст виклику методу й використовувати this для доступу до властивостей об’єкта.
thisУ JavaScript this — спеціальне ключове слово, яке посилається на об’єкт-контекст поточного виклику функції.
Коли функцію викликають як метод об’єкта, this посилається на цей об’єкт:
const user = {
name: "Олена",
sayHello: function () {
console.log(`Привіт, я ${this.name}`);
}
};
user.sayHello(); // Привіт, я ОленаУ цьому прикладі:
sayHello — метод об’єкта user;
user.sayHello() — виклик методу;
this усередині методу посилається на user;
this.name означає user.name.
Важливо: значення this залежить не від місця, де функцію написали, а від способу її виклику.
const firstUser = {
name: "Олена",
introduce: function () {
console.log(`Мене звати ${this.name}`);
}
};
const secondUser = {
name: "Андрій",
introduce: firstUser.introduce
};
firstUser.introduce(); // Мене звати Олена
secondUser.introduce(); // Мене звати АндрійМетод introduce написаний лише один раз. Але під час виклику:
firstUser.introduce();this посилається на firstUser.
А під час виклику:
secondUser.introduce();this посилається на secondUser.
Отже, одна й та сама функція може працювати з різними об’єктами.
thisЗа допомогою this метод може читати й змінювати властивості свого об’єкта:
const counter = {
value: 0,
increment: function () {
this.value = this.value + 1;
},
show: function () {
console.log(`Поточне значення: ${this.value}`);
}
};
counter.show(); // Поточне значення: 0
counter.increment();
counter.increment();
counter.show(); // Поточне значення: 2У методі increment вираз:
this.value = this.value + 1;можна прочитати так:
counter.value = counter.value + 1;Однак this робить метод універсальнішим: він працює з тим об’єктом, через який його викликали.
Методи одного об’єкта можуть викликати один одного через this:
const product = {
name: "Навушники",
price: 1500,
discount: 200,
getFinalPrice: function () {
return this.price - this.discount;
},
printInfo: function () {
const finalPrice = this.getFinalPrice();
console.log(`${this.name}: ${finalPrice} грн`);
}
};
product.printInfo(); // Навушники: 1300 грнУ методі printInfo:
this.name звертається до назви товару;
this.getFinalPrice() викликає інший метод цього самого об’єкта.
Властивість об’єкта потрібно читати через this:
const user = {
name: "Марія",
sayName: function () {
console.log(this.name);
}
};
user.sayName(); // МаріяЯкщо написати просто name, JavaScript шукатиме локальну змінну або змінну в зовнішній області видимості:
const user = {
name: "Марія",
sayName: function () {
// console.log(name); // Помилка, якщо змінної name не існує
console.log(this.name);
}
};
user.sayName();Запис:
user.sayHello();складається з двох частин:
user — об’єкт, на якому викликають метод;
sayHello — функція, яку викликають.
Саме об’єкт перед крапкою визначає значення this.
const admin = {
name: "Ірина",
sayHello: function () {
console.log(this.name);
}
};
admin.sayHello(); // ІринаУ цьому виклику об’єкт перед крапкою — admin, тому this === admin.
Якщо метод належить вкладеному об’єкту, this посилається саме на цей вкладений об’єкт:
const company = {
name: "Tech Company",
manager: {
name: "Дмитро",
introduce: function () {
console.log(`Керівник: ${this.name}`);
}
}
};
company.manager.introduce(); // Керівник: ДмитроТут this — це company.manager, а не company.
Метод не аналізує весь ланцюжок об’єктів. Він бере безпосередній об’єкт перед крапкою під час виклику.
Якщо зберегти метод в окрему змінну, він більше не викликається через об’єкт:
const user = {
name: "Олена",
sayHello: function () {
console.log(`Привіт, я ${this.name}`);
}
};
const greet = user.sayHello;
// greet(); // У strict mode this буде undefinedУ виклику greet() немає об’єкта перед крапкою. Тому метод втрачає контекст user.
Щоб зберегти контекст, можна викликати метод безпосередньо через об’єкт:
user.sayHello();Або явно прив’язати функцію до об’єкта за допомогою bind:
const user = {
name: "Олена",
sayHello: function () {
console.log(`Привіт, я ${this.name}`);
}
};
const greet = user.sayHello.bind(user);
greet(); // Привіт, я ОленаМетод bind створює нову функцію, у якої this назавжди прив’язаний до переданого об’єкта.
callМетод call дозволяє викликати функцію та вручну передати значення this:
const user = {
name: "Олена"
};
function sayName() {
console.log(`Ім’я: ${this.name}`);
}
sayName.call(user); // Ім’я: ОленаУ цьому випадку функція sayName не є методом user, але call(user) задає для її виклику this === user.
Для початкового використання методів зазвичай достатньо викликати функцію через об’єкт:
user.sayName();thisСтрілкові функції мають особливу поведінку: вони не створюють власного this. Вони використовують this із зовнішнього контексту.
Тому стрілкова функція зазвичай не підходить для методу, якому потрібен this самого об’єкта:
const user = {
name: "Олена",
sayHello: () => {
console.log(this.name);
}
};
user.sayHello(); // this не посилається на userДля методу об’єкта використовуйте звичайну функцію:
const user = {
name: "Олена",
sayHello: function () {
console.log(`Привіт, я ${this.name}`);
}
};
user.sayHello(); // Привіт, я ОленаТакож можна використовувати скорочений синтаксис методу:
const user = {
name: "Олена",
sayHello() {
console.log(`Привіт, я ${this.name}`);
}
};
user.sayHello(); // Привіт, я ОленаРозглянемо об’єкт кошика покупок:
const cart = {
items: [],
total: 0,
addItem(name, price) {
this.items.push({
name: name,
price: price
});
this.total += price;
},
showSummary() {
console.log(`Кількість товарів: ${this.items.length}`);
console.log(`Сума: ${this.total} грн`);
}
};
cart.addItem("Книга", 400);
cart.addItem("Рюкзак", 1200);
cart.showSummary();
// Кількість товарів: 2
// Сума: 1600 грнУ цьому прикладі:
this.items — масив товарів поточного кошика;
this.total — загальна сума поточного кошика;
this.items.push(...) додає товар до властивості об’єкта;
this.total += price змінює стан об’єкта.
const user = {
name: "Олена",
sayHello() {
console.log(this.name);
}
};
const sayHello = user.sayHello;
// sayHello(); // Контекст user втраченоПравильно:
user.sayHello();Або:
const sayHello = user.sayHello.bind(user);
sayHello();this визначається місцем оголошенняconst firstUser = {
name: "Олена",
sayName() {
console.log(this.name);
}
};
const secondUser = {
name: "Андрій",
sayName: firstUser.sayName
};
secondUser.sayName(); // Андрійthis визначається викликом secondUser.sayName(), а не тим, що функцію спочатку записали в firstUser.
const user = {
name: "Олена",
sayName: () => {
console.log(this.name);
}
};Якщо методу потрібен об’єкт у this, використовуйте звичайну функцію або скорочений синтаксис методу:
const user = {
name: "Олена",
sayName() {
console.log(this.name);
}
};this.name з namethis.name — властивість поточного об’єкта;
name — окрема змінна, яку JavaScript шукає в доступних областях видимості.
Створіть об’єкт bankAccount з такими властивостями й методами:
owner — ім’я власника;
balance — початковий баланс;
deposit(amount) — додає гроші до балансу;
withdraw(amount) — зменшує баланс, якщо коштів достатньо;
showBalance() — виводить поточний баланс.
Приклад очікуваної поведінки:
const bankAccount = {
owner: "Андрій",
balance: 1000,
deposit(amount) {
this.balance += amount;
},
withdraw(amount) {
if (amount <= this.balance) {
this.balance -= amount;
} else {
console.log("Недостатньо коштів");
}
},
showBalance() {
console.log(`${this.owner}: ${this.balance} грн`);
}
};
bankAccount.deposit(500);
bankAccount.withdraw(200);
bankAccount.showBalance(); // Андрій: 1300 грнthis посилається на контекст поточного виклику.
Під час виклику object.method() значення this — це object.
Через this метод отримує доступ до властивостей і методів об’єкта.
Контекст визначається під час виклику, а не під час оголошення функції.
Якщо зберегти метод в окрему змінну, його контекст можна втратити.
bind прив’язує функцію до конкретного об’єкта.
Стрілкові функції не мають власного this, тому їх потрібно обережно використовувати як методи об’єктів.