Методы и this
Объекты обычно не просто хранят данные, но и что-то делают. Герой получает урон, лечится, рассказывает о себе. Функции, принадлежащие классу, — это его методы. (В курсе JavaScript говорилось, что функцию, хранящуюся в объекте, называют методом, как log в console.log.) В классе метод пишут как функцию, только без слова function:
class Hero {
name: string;
health: number = 50;
constructor(name: string) {
this.name = name;
}
takeDamage(amount: number): void {
this.health = this.health - amount;
}
describe(): string {
return `${this.name}: здоровье ${this.health}`;
}
}
const kira = new Hero("Кира");
const bruno = new Hero("Бруно");
kira.takeDamage(15);
bruno.takeDamage(5);
console.log(kira.describe());
console.log(bruno.describe());Программа выводит:
Кира: здоровье 35
Бруно: здоровье 45Метод вызывают через точку, как вы уже привыкли: kira.takeDamage(15). Внутри метода this — это объект, у которого его вызвали. В kira.takeDamage(15) this — это kira, а в bruno.takeDamage(5) — bruno. Так один метод работает для каждого экземпляра: каждый вызов меняет здоровье того героя, что стоит перед точкой.
У методов есть типы, как у функций (урок «Функции»): типы параметров и тип возвращаемого значения. Здесь это void у takeDamage, который только меняет героя, и string у describe, который возвращает текст. TypeScript проверяет вызовы методов так же, как вызовы функций: kira.takeDamage("много") — это TS2345, а kira.heal(5) даёт Property 'heal' does not exist on type 'Hero'. (TS2339), пока в классе нет такого метода.
Методы хранятся один раз, в классе, и все его экземпляры пользуются общими. Поэтому console.log(kira) показывает только поля: Hero { name: "Кира", health: 35 }.
Типичные ошибки: чаще всего забывают this. в методе. Поле — это не переменная, к нему обращаются через объект. TypeScript даже подсказывает исправление:
class Hero {
name: string;
health: number = 50;
constructor(name: string) {
this.name = name;
}
takeDamage(amount: number): void {
health = health - amount;
}
}TypeScript сообщает:
main.ts(10,9): error TS2663: Cannot find name 'health'. Did you mean the instance member 'this.health'?
main.ts(10,18): error TS2663: Cannot find name 'health'. Did you mean the instance member 'this.health'?Ещё одна ошибка — забытые скобки. console.log(kira.describe) не вызывает метод, а выводит сам метод: [Function: describe]. TypeScript это позволяет, потому что метод — тоже значение.
Задание
- 1
Добавьте метод
heal(amount: number): void. Он прибавляетamountкhealthгероя, но не вышеmaxHealth: если сумма получилась бы больше,healthстановится равнымmaxHealth. В конце программы вылечите Киру на10и выведите еёhealth, затем вылечите на50и выведите снова. Программа выводит:20 30 50 - 2
Добавьте метод
describe(): string, который возвращает имя и здоровье героя так:Кира: 50/50. Выведитеkira.describe(). Затем создайте Бруно, пусть он получит5урона, и выведите и его описание:Кира: 50/50 Бруно: 45/50