TS和JS成员变量修饰符
|
zhenglin
2025年12月1日 14:35
本文热度 505
|
在 TypeScript 和 JavaScript 中,类成员变量(属性)的修饰符(Modifiers) 用于控制其可见性、可访问性和可变性。
两者在能力上有显著差异:TypeScript 提供了更丰富的编译时修饰符,而 JavaScript(ES2022 起)引入了运行时私有字段。
下面从 TypeScript 和 JavaScript 两个角度分别说明,并对比异同。
一、TypeScript 类成员变量修饰符(编译时)TypeScript 在 编译阶段 提供以下关键字作为访问修饰符:

✅ 示例(TypeScript):
class User {
public name: string; // 默认就是 public
private id: number; // TS 禁止外部访问
protected email: string; // 子类可访问
readonly createdAt: Date; // 初始化后不可改
constructor(name: string, id: number, email: string) {
this.name = name;
this.id = id;
this.email = email;
this.createdAt = new Date();
}
}
⚠️ 注意:
private / protected 只在 TypeScript 编译时生效,编译成 JS 后,这些字段仍是普通属性,运行时仍可被访问或修改!
// 编译后的 JS(无 private 保护!)
const user = new User("Alice", 1, "a@example.com");
console.log(user.id); // ✅ 能访问!JS 不报错
user.id = 999; // ✅ 能修改!
二、JavaScript 类成员变量修饰符(运行时,ES2022+)
从 ECMAScript 2022(ES13) 开始,JavaScript 原生支持 真正的私有字段(Private Fields) ,使用 # 前缀。

✅ 示例(JavaScript / TypeScript 均支持):
class User {
#id; // 私有字段(JS 原生私有)
name; // 公共字段
constructor(name, id) {
this.name = name;
this.#id = id; // 只能在类内部访问
}
getId() {
return this.#id; // ✅ OK
}
}
const user = new User("Bob", 2);
console.log(user.name); // ✅ "Bob"
console.log(user.#id); // ❌ SyntaxError! 无法访问
✅ 关键优势:
#id 是真正的私有,即使在运行时也无法绕过(除非用 Proxy 等 hack,但正常代码做不到)。
三、TypeScript 对 JS 私有字段的支持
TypeScript 完全支持 # 私有字段,并提供类型检查:
class User {
#id: number;
name: string;
constructor(name: string, id: number) {
this.name = name;
this.#id = id;
}
getId(): number {
return this.#id; // ✅ TS 知道这是 number
}
}
🔸 此时你不需要用 private,因为 #id 已经是运行时私有。
四、对比总结

五、最佳实践建议
✅ 优先使用 JavaScript 原生私有字段 #
✅ 在 TypeScript 中:
✅ 不要混用:
// ❌ 不推荐:语义重复且混乱
private #id; // 错误!不能同时用
readonly 仍是 TS 特有(JS 无等价物)
class Config {
readonly #apiUrl: string;
constructor(url: string) {
this.#apiUrl = url; // 初始化后不可变(TS 检查)
}
}
六、补充:其他相关修饰符

✅ 总结

🎯 现代项目建议:
用 # 实现私有,用 readonly 实现只读,放弃 private(除非必须兼容旧 JS) 。
这样既能获得类型安全,又能保证运行时封装性。
参考文章:原文链接
该文章在 2025/12/1 14:35:53 编辑过