JavaScript class 中的 getter 和 setter 是用于定义属性访问逻辑的特殊方法,支持数据验证、计算属性和状态封装;语法用 get/set 关键字声明,需避免命名冲突与状态修改陷阱。

在 JavaScript class 中,getter 和 setter 是用来定义对象属性的访问逻辑的特殊方法,让属性看起来像普通属性,实际读写时却能执行自定义代码。它们常用于数据验证、计算属性、封装内部状态等场景。
基本语法:用 get 和 set 关键字定义
在 class 内部,用 get 定义 getter(只读访问),用 set 定义 setter(只写或带校验的赋值)。两者必须成对出现(如果要双向控制),且不能与同名普通属性或方法冲突。
示例:
class Person {
constructor(name, age) {
this._name = name;
this._age = age;
}
// getter:访问 name 时触发
get name() {
return this._name.toUpperCase();
}
// setter:给 name 赋值时触发
set name(value) {
if (typeof value !== 'string' || value.trim() === '') {
throw new Error('姓名必须是非空字符串');
}
this._name = value.trim();
}
// 只读的计算属性(无对应 setter)
get isAdult() {
return this._age >= 18;
}
}
使用方式:像普通属性一样读写,不加括号
调用 getter 或 setter 时,语法和访问普通属性完全一致——不需要加 (),也不需要显式调用 set 或 get。
const p = new Person('alice', 25);console.log(p.name); // "ALICE" —— 触发 getterp.name = ' bob '; // 触发 setter,内部转为 'bob'console.log(p.isAdult); // true —— 只读计算属性p.isAdult = false; // 无效,没有 setter,赋值被忽略(静默)
注意事项和常见陷阱
- getter 中不要修改实例状态(比如改
this._xxx),否则可能引发无限递归或意外行为 - setter 的参数名不能和 getter 名相同(否则会触发自身,造成栈溢出),务必用不同名称(如
_name)存值 - 不能同时存在同名的普通属性和 accessor(例如既有
this.name = 'x',又有get name()),后者会覆盖前者 - 继承中可重写 getter/setter:子类可用
super.name访问父类的 accessor,但需确保父类已定义
实用场景举例
- 数据格式化:如把邮箱统一转小写再返回
- 输入校验:年龄设为负数时抛错或自动修正
- 依赖响应:某个属性变化时自动更新另一个缓存值(如 fullName 改变时触发 firstName/lastName 拆分)
- 兼容旧 API:用 accessor 封装老字段,对外保持简单属性接口,内部升级逻辑不影响调用方
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











