本文详解 TypeScript 2.0 引入的 readonly 关键字。介绍如何在 interface 和 type 中定义只读属性,限制类中属性的修改(仅限构造函数),以及函数参数只读的应用。同时说明 readonly 仅作用于编译时,运行时无效,并展示 ReadonlyArray 防止索引赋值的方法。
前言
TypeScript 2.0 版本引入了 readonly 关键字,用于修饰类中的属性。其核心作用是确保该属性一旦赋值便不可更改(唯一的例外是在构造函数内部可以对其进行初始化赋值)。
在 interface 和 type 定义中,可以直接使用 readonly 关键字来标记属性。
以下是一个简单的示例:我们定义一个名为 User 的类型。
type User={
readonly name : string;
readonly age : number
}接着,我们可以创建一个 user 实例,并为其初始化具体的属性值。
let user:User={
name:'搞前端的半夏',
age:18
}如果尝试修改 age 的值,TypeScript 编译器会直接报错。
user.age=19
只读函数参数
在 JavaScript 中,我们常使用 const 定义变量,但 const 无法保证对象内部属性不被修改。沿用上面的 User 类型,
假设有一个函数接收 User 类型的参数。如果在函数内部尝试修改 age 属性,编译时将直接报错。
这样做的好处在于:我们可以确保在此处定义的全局 user 对象不会被意外修改。
let user:User={
name:'搞前端的半夏',
age:18
}
UserInfo(user)function UserInfo(user:User){
user.age=19
console.log(user.name,user.age)
}
如何更改函数
只读类属性
readonly 修饰符同样适用于类中声明的属性。这里我们创建了一个 User 类,包含只读的 name 和 age 属性,请注意这两个属性在声明时没有初始值。
class User {
readonly name: string;
readonly age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
UserInfo(user:User){
console.log(user.name,user.age)
}
}当我们使用 new 关键字创建 user 实体时,可以在构造函数中为 name 和 age 赋予默认值。由此可以得出结论:
在类的 constructor 中,我们可以修改只读属性的值。
对于 name 和 age 这两个只读属性,我们可以正常获取其具体值。
let user =new User('搞前端的半夏',18)
console.log(user.name)
console.log(user.age)然而,如果尝试在类的方法中修改 name 和 age 的值,编译器会报错。

我们尝试在 UserInfo 方法中修改 name 和 age:
UserInfo(user:User){
this.age=20
console.log(user.name,user.age)
}可以看到,编译仍然报错!我们可以得出结论:
在类的普通方法中,无法修改被 readonly 修饰的属性。

只读索引
可以使用 readonly 来标记索引签名。例如下面的 ReadonlyArray,可以有效防止对具体索引进行赋值操作。
interface ReadonlyArray<T> {
readonly length: number;
// ...
readonly [n: number]: T;
}由于是只读索引,下面的赋值操作会导致编译错误。
const readonlyArray: ReadonlyArray<number> = [2, 3, 5, 7];
readonlyArray[4] = 11;
总结
readonly 是 TypeScript 类型系统的一部分,它仅是一个编译时的工具。当 TypeScript 代码被编译为 JavaScript 后,所有的readonly标记都会消失。因此,在运行时没有任何针对属性只读的保护机制。TypeScript 是通过编译器检查来帮助你编写正确的代码。
例如在下面的示例中,即使编译器提示有错误,TypeScript 仍然可以编译生成对应的 JavaScript 代码。这也充分说明 TypeScript 仅在编译阶段引导我们规范编码。

到此这篇关于 TypeScript 只读修饰符的文章就介绍到这了,更多相关 TypeScript 只读修饰符内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!