介绍
readonly 用于将 属性、数组 标记为 只读。一旦被赋值,就不能再被修改。
注意:不能修饰普通变量,否则报错
有助于提高代码的可读性、可维护性和安全性,尤其是在处理 不可变数据时。
标记只读属性 (类中)
这是最常见的用法。防止类的 属性 在实例化后被修改。
注意:只能在 声明时 或 构造函数中被赋值。
声明时赋值
class Mate80 {
// 常量实例属性
readonly cpu:string = "麒麟9900"
}
let lileiMate80 = new Mate80()
// 修改值报错
lileiMate80.cpu = "麒麟9800"
构造方法中赋值
class Mate80 {
// 常量实例属性
readonly cpu:string = "麒麟9900"
constructor(cpu:string) {
// 在构造方法中赋值
this.cpu = cpu
}
modify(){
// 在其他方法中不能赋值
// this.cpu = "麒麟9800"
}
}
let lileiMate80 = new Mate80("麒麟9999")
// 修改值报错
// lileiMate80.cpu = "麒麟9800"
标记接口中的只读属性
在接口中定义不可变的数据结构。
interface Point {
readonly x: number;
readonly y: number;
}
const origin: Point = { x: 0, y: 0 };
// origin.x = 5; // ❌ 错误!
标记只读数组(不在类中)
使用 readonly T[] 类型,创建一个 不可修改 的数组,但 可以重新赋值
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];
函数参数是数组类型
防止在函数内部意外 修改传入的对象或数组,但 可以重新赋值
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 |
|---|---|---|
| 作用对象 | 属性 (对象的字段) | 变量 |
| 修改 | 不能修改该属性的值 | 不能重新赋值 |
| 适用范围 | 类属性、接口属性、数组元素 | 变量声明 |
| 层级 | 更细粒度,控制对象内部 | 更粗粒度,控制变量引用 |
对比示例
// ✅ 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
可以组合使用,创建一个私有的、只读的属性。
class Secret {
private readonly key: string;
constructor(key: string) {
this.key = key; // 只能在构造函数中赋值
}
// 其他方法可以读取 key,但不能修改
getKeyHash(): string {
return this.key + "-hashed";
}
}
总结
readonly是一个编译时检查,用于标记属性、数组或对象属性为只读。- 它不能阻止变量重新赋值(那是
const的工作),而是阻止修改属性的值。 - 与
const结合使用,可以创建完全不可变的数据。