Поля только для чтения
Некоторые значения не должны меняться после создания объекта: имя героя, номер задания, id в файле сохранения. В уроке «Типы объектов» вы помечали такие свойства как readonly, и поля класса работают так же:
class Hero {
readonly id: number;
readonly name: string;
level: number = 1;
constructor(id: number, name: string) {
this.id = id;
this.name = name;
}
rename(newName: string): void {
this.name = newName;
}
}
const kira = new Hero(1, "Кира");
kira.name = "Кираа";TypeScript сообщает:
main.ts(12,14): error TS2540: Cannot assign to 'name' because it is a read-only property.
main.ts(17,6): error TS2540: Cannot assign to 'name' because it is a read-only property.Поле readonly получает значение либо как начальное, либо в конструкторе, и присвоить его можно только в этих двух местах. После этого изменить его не может никто: ни код снаружи класса, ни даже собственные методы класса, как rename выше. Читать можно где угодно: kira.name — это нормально.
readonly или private? Они защищают разное:
private— о том, кто может пользоваться полем: только класс может его читать и менять.readonly— о том, когда его можно менять: только пока создаётся объект. Читать может кто угодно.
Их можно сочетать: private readonly secret: string; — это поле, которое может читать только класс и которое никогда не меняется. А если сравнивать с const: const — для переменных, readonly — для полей и свойств.
Как и private, readonly существует только для TypeScript; в работающем JavaScript это обычное свойство. Но TypeScript проверяет всю программу до запуска, поэтому ни одна строка вашей программы не сможет изменить такое поле.
Поле только для чтения ловит не только намеренные изменения. Помните классическую ошибку из курса JavaScript — = вместо === в условии? В программе в редакторе она есть.
Задание
- 1
Запустите программу: она выводит
Бруно здесь!, а Кира вдруг оказывается Бруно. Сделайте поляidиnameтолько для чтения. Тогда TypeScript отметит строку с ошибкой; исправьте её так, чтобы имя сравнивалось, а не присваивалось. Кира остаётся Кирой:Hero { id: 1, name: "Кира", level: 2 } - 2
Добавьте после
nameтретье поле только для чтения:heroClassтипаHeroClass(этот тип объявлен в начале программы). Конструктор получает его третьим параметром. Создайте Киру следопытом:new Hero(1, "Кира", "следопыт"). Тогда программа выводит:Hero { id: 1, name: "Кира", heroClass: "следопыт", level: 2 }