JavaScript class 中 getter 和 setter 用于控制属性读写,语法简洁;可单独存在,支持私有字段、计算属性名;需避免递归调用、副作用及赋值无效等问题。

在 JavaScript class 中,getter 和 setter 是定义访问器属性的标准方式,用于控制对某个属性的读取和写入行为,同时保持调用语法像普通属性一样简洁自然。
基础写法:用 get/set 关键字声明
在 class 内部直接使用 get 和 set 关键字定义方法,方法名就是对外暴露的属性名:
- getter 方法无参数,必须有 return 值,调用时写作
obj.propName(不加括号) - setter 方法必须且仅有一个参数(即赋值表达式的右值),内部可做校验、拆解或状态同步
- getter 和 setter 可以单独存在;只有 getter 时属性天然只读,尝试赋值在严格模式下会报
TypeError
示例:
${this._first} ${this._last}
配合私有字段增强封装性
ES2022+ 支持私有类字段(#前缀),与 getter/setter 结合能真正隔离内部状态:
- 私有字段无法被外部直接访问,避免绕过逻辑篡改
- 所有读写都必须经过 getter/setter,便于统一拦截、日志、响应式触发等
- 注意:私有字段名在 getter/setter 内部也要带
#,否则会访问到不存在的属性
示例:
class Counter {
#https://www.php.cn/link/ab0b7a8494bc0c458fa9dd1d44d832f6ue = 0;
<p>get count() {
return this.#https://www.php.cn/link/ab0b7a8494bc0c458fa9dd1d44d832f6ue;
}</p><p>set count(https://www.php.cn/link/ab0b7a8494bc0c458fa9dd1d44d832f6) {
if (Number.isInteger(https://www.php.cn/link/ab0b7a8494bc0c458fa9dd1d44d832f6) && https://www.php.cn/link/ab0b7a8494bc0c458fa9dd1d44d832f6 >= 0) {
this.#https://www.php.cn/link/ab0b7a8494bc0c458fa9dd1d44d832f6ue = https://www.php.cn/link/ab0b7a8494bc0c458fa9dd1d44d832f6;
}
}
}</p>
计算属性名(Computed Property Names)支持
getter 和 setter 同样支持方括号语法的动态属性名,适用于需要运行时确定键名的场景:
- 写法与对象字面量一致:
get [computedKey]() { ... } - 常用于构建通用访问器、按配置生成属性、或与 Symbol 配合实现隐藏接口
- 注意:计算名必须是字符串或 Symbol,不能是任意表达式(需提前求值)
示例:
const PROP_NAME = 'status';
<p>class Task {</p><h1>state = 'pending';</h1><p>get [PROP_NAME]() {
return this.#state;
}</p><p>set <a href="https://www.php.cn/link/ab0b7a8494bc0c458fa9dd1d44d832f6">PROP_NAME</a> {
if (['pending', 'done', 'error'].includes(https://www.php.cn/link/ab0b7a8494bc0c458fa9dd1d44d832f6)) {
this.#state = https://www.php.cn/link/ab0b7a8494bc0c458fa9dd1d44d832f6;
}
}
}</p>
常见误区与注意事项
实际使用中容易踩坑的地方:
- 不要在 getter 中直接读取同名属性(如
get name() { return this.name; }),会无限递归调用导致栈溢出 - setter 中若未显式更新底层数据,赋值操作看似成功但无实际效果
- getter 不应有副作用(如发请求、修改其他状态),因为它可能被频繁、不可控地调用
- 继承时子类可重写父类的 getter/setter,但需注意
super.propName的访问方式











