JavaScript class 中可用 getter/setter 拦截属性读写,实现验证、计算等逻辑;需配合私有字段(#)或下划线字段(_)避免递归;其为访问器属性,不被 Object.keys() 枚举。

在 JavaScript class 中,用 getter 和 setter 可以拦截对某个属性的读取和赋值操作,实现数据验证、计算属性、副作用控制等逻辑,而无需暴露原始字段。
定义 getter 和 setter 的基本语法
在 class 内部,用 get 和 set 关键字声明同名方法,它们必须成对或单独存在(不强制配对),且不能与普通方法同名:
- getter 无参数,返回值即为属性读取的结果
- setter 必须有且仅有一个参数(即赋值时的右值)
- 通常配合私有字段(如
#value)或下划线命名的受保护字段(如_value)来存储实际数据,避免递归调用
示例:
class Person {constructor(name) {
this._name = name;
}
get name() {
return this._name.trim(); // 读取时自动清理空格
}
set name(value) {
if (typeof value !== 'string' || value.trim() === '') {
throw new Error('姓名必须是非空字符串');
}
this._name = value;
}
}
用私有字段(#)避免命名冲突和外部篡改
ES2022 起支持真正的私有字段(以 # 开头),推荐用于封装内部状态,防止 getter/setter 中意外访问到同名公有属性:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 私有字段只能在 class 内部访问,外部无法读写,更安全
- getter/setter 中直接操作
#value,不会触发自身,杜绝无限递归
示例:
class Temperature {#celsius;
constructor(celsius) {
this.#celsius = celsius;
}
get fahrenheit() {
return (this.#celsius * 9) / 5 + 32;
}
set fahrenheit(value) {
this.#celsius = ((value - 32) * 5) / 9;
}
}
注意:getter/setter 不会出现在 for...in 或 Object.keys() 中
它们属于对象的访问器属性(accessor property),不是数据属性(data property):
-
Object.getOwnPropertyDescriptor(obj, 'prop')可查看是否为get/set -
Object.keys(obj)和for...in只枚举可枚举的数据属性,不包含 getter/setter - 但
in操作符、点号访问、解构仍能正常工作
常见误用与规避方式
- 不要在 getter 中修改 this 状态(如发请求、改其他字段),它可能被多次无意调用(如模板渲染、JSON.stringify)
- 避免在 setter 中直接调用
this.prop = value(会再次触发 setter,导致栈溢出)——务必操作底层存储字段(如this.#x或this._x) - 如果需要监听属性变化并响应,考虑用
Proxy替代,尤其当需拦截多个属性或动态属性时

















