ES6类中用get/set定义getter/setter可拦截属性读写,实现校验、计算等逻辑;getter无参返回动态值,setter单参处理赋值并校验,需配合私有字段避免递归。

ES6 类中用 get 和 set 关键字定义 getter/setter,可以拦截对实例属性的读取和赋值操作,实现数据校验、计算属性、副作用控制等逻辑。
getter:拦截属性读取
getter 是一个无参函数,返回值就是访问该属性时得到的结果。它不会真正存储值,而是每次读取时动态计算或返回代理值。
- 语法:在类内部用
get 属性名() { return ... }定义 - 调用方式:像普通属性一样读取,如
obj.fullName,不加括号 - 常见用途:组合字段(如拼接 first + last)、格式化输出、权限控制(返回脱敏数据)
示例:
class User {
constructor(first, last) {
this.first = first;
this.last = last;
}
get fullName() {
return `${this.first} ${this.last}`.trim();
}
}
const u = new User('John', 'Doe');
console.log(u.fullName); // "John Doe"setter:拦截属性赋值
setter 是一个单参函数,参数接收赋值表达式的右值。它不返回值,主要用于验证、转换或触发其他逻辑。
立即学习“Java免费学习笔记(深入)”;
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
- 语法:用
set 属性名(value) { ... }定义 - 调用方式:像普通属性一样赋值,如
obj.age = 25 - 注意:必须与同名 getter 成对出现才能拦截原始属性;否则需配合私有字段或 Symbol 避免无限递归
示例(带校验):
class Person {
constructor(age) {
this._age = age; // 用私有命名约定存储真实值
}
get age() {
return this._age;
}
set age(value) {
if (typeof value !== 'number' || value < 0 || value > 150) {
throw new Error('年龄必须是 0–150 的数字');
}
this._age = value;
}
}搭配私有字段(#)避免递归
ES2022 起支持真正的私有字段(#name),推荐用于 setter/getter 内部存储,彻底避免 this.age = value 触发自身 setter 导致栈溢出。
- 私有字段只能在类内部访问,外部不可见不可改
- getter/setter 中直接读写
this.#value,安全又语义清晰
示例:
class Temperature {
#celsius = 0;
get celsius() {
return this.#celsius;
}
set celsius(value) {
if (value < -273.15) throw new Error('低于绝对零度');
this.#celsius = value;
}
get fahrenheit() {
return (this.#celsius * 9/5) + 32;
}
}不能单独重写原型上的 getter/setter
类中定义的 getter/setter 默认添加到类的 prototype 上,所有实例共享。但无法像普通方法那样在实例上直接覆盖(除非用 Object.defineProperty 手动设置实例属性)。
- 若想为某个实例定制行为,需在构造函数中用
Object.defineProperty(this, 'prop', {...}) - 不建议在运行时频繁修改 descriptor,影响性能和可读性
不复杂但容易忽略。

















