TypeScript 只读属性
在TypeScript中,属性是定义对象结构和行为的重要部分。它们允许我们封装数据并提供访问和操作数据的途径。默认情况下,TypeScript中的属性既可以被读取又可以被写入,也就是说可以被访问和修改。然而,有些情况下我们可能希望创建只能被读取而不能被修改的属性。这就是只读属性的作用。
只读属性提供了一种定义只能被访问而不能被更改的属性的方式。在需要确保某些数据保持不变且不能被意外修改的场景中特别有用。在本教程中,我们将探讨TypeScript中的只读属性,了解它们的工作原理,并看到它们使用的实际例子。
语法
要在TypeScript中定义只读属性,我们在属性名前加上 readonly 关键字。
封装实体可以是TypeScript中的类或接口。
class MyClass {
readonly propertyName: type;
}
你可以用你的类名替换 MyClass , 用于只读属性的 propertyName ,和 适当的数据类型用 type 替换。
理解只读属性
这些只读属性只能读取,不能修改。任何修改只读属性的尝试都会导致编译时错误。此外,请注意,TypeScript中没有运行时检查来强制执行这一点,生成的JavaScript等价代码没有验证只读属性的方法。
在下面的示例中,Person类的name和age属性被标记为只读属性。一旦这些属性被赋值,它们的值就不能更改,任何尝试都会导致lint和编译时错误。
class Person {
readonly name: string;
readonly age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
只读属性的使用和好处
只读属性在TypeScript开发中提供了多个好处和用例。让我们探索一下其中的一些好处。
示例1: 不可改变的对象
只读属性可以用来创建不可改变的对象。不可改变的对象是一个在创建后其状态不能被改变的对象。通过将所有属性标记为只读,我们确保对象的状态在其生命周期内保持不变。这在某些场景中特别有用,例如你想要确保某些数据保持不变,防止意外修改可能引入错误或意外行为的情况发生。
class Circle {
readonly radius: number;
readonly area: number;
constructor(radius: number) {
this.radius = radius;
this.area = Math.PI * radius * radius;
}
}
const circle = new Circle(5);
console.log(`The area of the circle is: ${circle.area}`); // Output: 78.53981633974483
// circle.area = 100;
在编译时,它将生成以下JavaScript代码−
var Circle = /** @class */ (function () {
function Circle(radius) {
this.radius = radius;
this.area = Math.PI * radius * radius;
}
return Circle;
}());
var circle = new Circle(5);
console.log("The area of the circle is: ".concat(circle.area)); // Output: 78.53981633974483
// circle.area = 100;
输出
上面的代码将产生以下输出 –
The area of the circle is: 78.53981633974483
在上面的例子中,Circle类的半径和面积属性被标记为只读。一旦创建Circle对象,就无法修改其属性,以确保计算出的面积保持恒定并与半径值一致。 最后一行尝试修改circle对象的只读属性 area ,因此会导致错误。您可以取消对上面这行代码的注释来验证。
Error: Cannot assign to 'area' because it is a read-only property.
示例2:安全重构
只读属性在重构代码时也起着重要作用。当你将一个属性标记为只读时,TypeScript编译器会帮助你识别并防止对该属性的意外修改。如果你尝试修改一个只读属性,编译器会抛出一个错误,使得在开发过程中更容易捕获和修复潜在的错误。
class Car {
readonly brand: string;
readonly model: string;
constructor(brand: string, model: string) {
this.brand = brand;
this.model = model;
}
}
const car = new Car("Toyota", "Corolla");
console.log(`The brand of the car is: ${car.brand}`); // Output: "Toyota"
// car.brand = "Honda"; // Error: Cannot assign to 'brand' because it is a read-only property
在编译时,它将生成以下JavaScript代码−
var Car = /** @class */ (function () {
function Car(brand, model) {
this.brand = brand;
this.model = model;
}
return Car;
}());
var car = new Car("Toyota", "Corolla");
console.log("The brand of the car is: ".concat(car.brand)); // Output: "Toyota"
// car.brand = "Honda"; // Error: Cannot assign to 'brand' because it is a read-only property
输出
上述代码将产生以下输出:
The brand of the car is: Toyota
在以上示例中,Car类的brand和model属性被标记为只读。如果我们尝试给brand属性赋新值,TypeScript编译器将引发错误,防止意外修改。
示例3:增强的可读性和意图
通过使用只读属性,我们可以更明确地传达某些属性的预期行为和用法。当您在类或接口中遇到只读属性时,它变得明显,该值不应被修改。这提高了代码的可读性,并使其他开发人员更容易理解代码库并遵循最佳实践。
interface Point {
readonly x: number;
readonly y: number;
}
function calculateDistance(point1: Point, point2: Point): number {
const dx = point2.x - point1.x;
const dy = point2.y - point1.y;
return Math.sqrt(dx * dx + dy * dy);
}
const point1: Point = { x: 0, y: 0 };
const point2: Point = { x: 3, y: 4 };
// point1.x = 5; // Error: Cannot assign to 'x' because it is a read-only property.
console.log(
`The distance between the points is: ${calculateDistance(point1, point2)}`
); // Output: 5
在编译时,它将生成以下JavaScript代码−
function calculateDistance(point1, point2) {
var dx = point2.x - point1.x;
var dy = point2.y - point1.y;
return Math.sqrt(dx * dx + dy * dy);
}
var point1 = { x: 0, y: 0 };
var point2 = { x: 3, y: 4 };
// point1.x = 5; // Error: Cannot assign to 'x' because it is a read-only property.
console.log("The distance between the points is: ".concat(calculateDistance(point1, point2))); // Output: 5
输出
上述代码将产生以下输出 –
The distance between the points is: 5
在上面的示例中,Point接口的x和y属性被标记为只读。这明确表明在计算距离过程中,点的坐标不可改变。
结论
TypeScript中的只读属性允许我们定义只能读取而不能修改的属性。使用readonly关键字可以强制不可变性,防止对某些数据的意外修改。只读属性具有多种好处,包括创建不可变对象、更安全的重构和改善代码可读性。它们在保持代码完整性、在开发过程中捕捉潜在错误和传达属性的预期行为方面起着关键作用。
在设计TypeScript类和接口时,应考虑在适当的情况下使用只读属性,以确保数据一致性并减少通过意外修改引入意外行为的可能性。通过有效利用只读属性,您可以创建更健壮可靠的TypeScript代码库。