TypeScript 中的只读属性
在 TypeScript 中,属性是定义对象结构和行为的重要组成部分。它们允许我们封装数据并提供访问和操作数据的方法。默认情况下,TypeScript 中的属性既可读又可写,这意味着它们既可以访问也可以修改。但是,在某些情况下,我们可能希望创建只能读取而不能修改的属性。这就是只读属性发挥作用的地方。
只读属性提供了一种定义只能访问而不能更改其值后修改的属性的方法。当您希望确保某些数据保持不变并且不会意外修改时,它们特别有用。在本教程中,我们将探讨 TypeScript 中的只读属性,了解它们的工作原理,并查看其用法的实际示例。
语法
要在 TypeScript 中定义只读属性,我们在属性名前加readonly关键字。
封装实体可以在 TypeScript 中是类或接口。
class MyClass { readonly propertyName: type; }
您可以将MyClass替换为您类的名称,将propertyName替换为只读属性所需的名称,并将type替换为适当的数据类型。
理解只读属性
这些只读属性只能读取,永远不能修改。任何尝试修改只读属性的操作都将导致编译时错误。另外,请注意,TypeScript 中没有运行时检查来强制执行此操作,并且生成的 JavaScript 等效代码没有任何方法来验证只读属性。
在下面的示例中,Person 类的 name 和 age 属性被标记为只读。一旦这些属性被分配了一个值,它们的値就不能更改,任何尝试都将导致 linting 和编译时错误。
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 类的 radius 和 area 属性被标记为只读。一旦创建了 Circle 对象,其属性就不能修改,从而确保计算出的 area 保持不变,并且与 radius 值一致。
最后一行尝试修改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 代码库。