TypeScript:readonly只读关键字 作者:马育民 • 2025-10-12 20:35 • 阅读:10000 # 介绍 `readonly` 用于将 **属性、数组** 标记为 **只读**。一旦被赋值,就不能再被修改。 **注意:**不能修饰普通变量,否则报错 有助于提高代码的可读性、可维护性和安全性,尤其是在处理 **不可变数据时**。 # 标记只读属性 (类中) 这是最常见的用法。防止类的 **属性** 在实例化后被修改。 **注意:**只能在 **声明时** 或 **构造函数中被赋值**。 ### 声明时赋值 ``` class Mate80 { // 常量实例属性 readonly cpu:string = "麒麟9900" } let lileiMate80 = new Mate80() // 修改值报错 lileiMate80.cpu = "麒麟9800" ``` ### 构造方法中赋值 ```typescript class Mate80 { // 常量实例属性 readonly cpu:string = "麒麟9900" constructor(cpu:string) { // 在构造方法中赋值 this.cpu = cpu } modify(){ // 在其他方法中不能赋值 // this.cpu = "麒麟9800" } } let lileiMate80 = new Mate80("麒麟9999") // 修改值报错 // lileiMate80.cpu = "麒麟9800" ``` # 标记接口中的只读属性 在接口中定义不可变的数据结构。 ```typescript interface Point { readonly x: number; readonly y: number; } const origin: Point = { x: 0, y: 0 }; // origin.x = 5; // ❌ 错误! ``` # 标记只读数组(不在类中) 使用 `readonly T[]` 类型,创建一个 **不可修改** 的数组,但 **可以重新赋值** ```typescript let numbers: readonly number[] = [1, 2, 3]; // numbers.push(4); // ❌ 错误!没有 push 方法 // numbers[0] = 10; // ❌ 错误!不能通过索引修改 // numbers.length = 0; // ❌ 错误!不能修改 length // ✅ 但可以读取 console.log("",numbers[0]); // 1 console.log("",numbers.length); // 3 ``` ### 可以重新赋值整个数组 ``` numbers = [4, 5, 6]; ``` ### 函数参数是数组类型 防止在函数内部意外 **修改传入的对象或数组**,但 **可以重新赋值** ```typescript function processArray(arr: readonly string[]) { // arr.push("new"); // ❌ 错误!不能修改 // arr = ["11","222"] // 可以重新赋值数组 console.log(arr[0]); } const myArray = ["a", "b", "c"]; processArray(myArray); // ✅ 可以传入普通数组 ``` # readonly 与 const 对比 这是初学者常混淆的两个概念,它们的作用层级不同: | 特性 | `readonly` | `const` | | :--- | :--- | :--- | | **作用对象** | **属性** (对象的字段)| **变量** | | **修改** | 不能修改该**属性**的值 | 不能重新赋值 | | **适用范围** | 类属性、接口属性、数组元素 | 变量声明 | | **层级** | 更细粒度,控制对象内部 | 更粗粒度,控制变量引用 | ### 对比示例 ```typescript // ✅ const 限制变量本身不能重新赋值 const person = { name: "Alice", age: 30 }; // person = { name: "Bob", age: 25 }; // ❌ 错误!不能改变 person 的指向 // ✅ 但可以修改 person 对象内部的属性(除非属性是 readonly) person.age = 31; // ✅ 可以修改 // ✅ 结合使用:既不能改变变量,也不能改变属性 const readonlyPerson: { readonly name: string; readonly age: number } = { name: "Alice", age: 30, }; // readonlyPerson.age = 31; // ❌ 错误!属性是 readonly // readonlyPerson = { name: "Bob", age: 25 }; // ❌ 错误!变量是 const ``` # readonly 与 private 可以组合使用,创建一个**私有的、只读的**属性。 ```typescript class Secret { private readonly key: string; constructor(key: string) { this.key = key; // 只能在构造函数中赋值 } // 其他方法可以读取 key,但不能修改 getKeyHash(): string { return this.key + "-hashed"; } } ``` # 总结 * `readonly` 是一个**编译时检查**,用于标记属性、数组或对象属性为只读。 * 它**不能阻止变量重新赋值**(那是 `const` 的工作),而是阻止**修改属性的值**。 * 与 `const` 结合使用,可以创建完全不可变的数据。 原文出处:http://malaoshi.top/show_1GW21ts7dcpL.html