本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
鸿蒙(HarmonyOS)开发中,const
和 readonly
都用于定义不可变的变量或属性,但它们的应用场景和行为有显著区别:
1. const
:编译时常量
特点
- 作用范围:仅用于变量声明(
let
和var
的替代)。 - 赋值时机:必须在声明时初始化,且后续不可修改。
- 类型推断:自动推断为字面量类型(如
const x = 10
的类型是10
,而非number
)。 - 编译行为:在编译阶段会被直接替换为常量值(类似宏替换)。
示例
const PI = 3.14; // 声明时必须初始化
// PI = 3.14159; // 编译错误:无法重新赋值
const config = { name: "HarmonyOS" };
config.name = "OpenHarmony"; // 允许!const 仅限制引用不可变,对象属性仍可变
适用场景
- 定义全局或局部常量(如数学常量、配置项)。
- 需要编译时优化的简单值。
2. readonly
:运行时常量
特点
- 作用范围:主要用于类属性、接口属性或对象属性。
- 赋值时机:
- 类属性:可在声明时或构造函数中初始化。
- 接口/对象:必须在声明时初始化。
- 类型行为:保留原始类型(如
readonly x: number
的类型是number
)。 - 运行行为:在运行时检查赋值操作,禁止修改。
示例
(1)类属性
class Device {
readonly id: string;
constructor(id: string) {
this.id = id; // 允许在构造函数中赋值
}
}
const d = new Device("123");
// d.id = "456"; // 编译错误:不可修改
(2)接口/对象
interface AppConfig {
readonly version: string;
}
const config: AppConfig = { version: "1.0" };
// config.version = "2.0"; // 编译错误:不可修改
适用场景
- 定义对象或类的不可变属性(如组件配置、实体类ID)。
- 需要运行时保护的复杂数据结构。
核心区别对比
特性 | const | readonly |
---|---|---|
作用对象 | 变量 | 类属性、接口属性、对象属性 |
可变性 | 引用不可变(对象属性可变) | 属性完全不可变 |
初始化时机 | 声明时必须初始化 | 类属性可在构造函数中初始化 |
类型推断 | 推断为字面量类型(如 10 ) | 保留原始类型(如 number ) |
编译/运行时 | 编译时替换为值 | 运行时检查 |
实际应用建议
- 基础常量 使用
const
定义简单值(如字符串、数字):
const MAX_USERS = 100;
2. 对象/类属性 使用 readonly
确保深层不可变性
interface User {
readonly id: string;
name: string;
}
const user: User = { id: "001", name: "Alice" };
// user.id = "002"; // 禁止
user.name = "Bob"; // 允许
3. 结合使用 对对象引用和属性同时锁定
const DEFAULT_CONFIG: Readonly<AppConfig> = { version: "1.0" };
// DEFAULT_CONFIG.version = "2.0"; // 禁止(Readonly 泛型将所有属性设为 readonly)
常见误区
- 误区1:认为
const
能完全冻结对象。 纠正:const
仅限制变量引用,对象属性仍可变。需配合Object.freeze()
或Readonly<T>
。 - 误区2:在构造函数外给
readonly
属性赋值。 纠正:readonly
类属性只能在声明时或构造函数中初始化。