getter与setter可实现在属性读写时自动校验,如限制年龄为0–150整数;需用object.defineproperty定义,不可与writable共存;支持静默修正、symbol闭包封装及class私有字段。

通过 Getter 与 Setter 可以在属性被读取或赋值时插入自定义逻辑,实现赋值即校验,无需每次手动调用验证函数。
基础语法:用 Object.defineProperty 定义存取器
原生对象属性默认是可写、可枚举、可配置的。要添加校验逻辑,需用 Object.defineProperty 显式定义 getter 和 setter:
- setter 接收新值,可在其中做类型检查、范围限制、格式校验等;校验失败可抛错或静默修正
- getter 负责返回值(通常从私有属性或内部变量读取)
- 不能同时设置
writable: true和get/set,二者互斥
实际示例:限制年龄为 0–150 的整数
以下代码确保 person.age 每次赋值都即时校验:
const person = {};
let _age = 25; // 私有存储变量
Object.defineProperty(person, 'age', {
get() {
return _age;
},
set(value) {
if (!Number.isInteger(value)) {
throw new TypeError('年龄必须是整数');
}
if (value 150) {
throw new RangeError('年龄必须在 0 到 150 之间');
}
_age = value;
}
});
person.age = 30; // ✅ 正常赋值
person.age = -5; // ❌ 抛出 RangeError
进阶技巧:支持默认值与静默修正
若不想中断流程,可将非法值自动修正为合理默认值:
- 例如把负数年龄设为 0,超大值设为 150
- setter 内部修正后仍触发更新逻辑(如触发视图刷新、事件通知)
- 配合 Symbol 或闭包变量避免属性名冲突,提升封装性
示例中将 _age 替换为 Symbol('age') 可防止外部直接访问:
const ageSym = Symbol('age');
const person = {};
Object.defineProperty(person, 'age', {
get() { return this[ageSym] ?? 0; },
set(value) {
this[ageSym] = Number.isInteger(value) && value >= 0 && value
<h3>Class 中使用 getter/setter 更简洁</h3>
<p>ES6 Class 支持更直观的语法,适合封装带校验的实例属性:</p>
<pre class="brush:php;toolbar:false;">class User {
constructor(name, age) {
this.name = name;
this.age = age; // 触发 setter 校验
}
set age(value) {
if (typeof value !== 'number' || value 150) {
throw new Error(`无效年龄: ${value}`);
}
this._age = value;
}
get age() {
return this._age;
}
}
const u = new User('Alice', 28); // ✅
u.age = 160; // ❌ 报错
注意:Class 中的 setter/getter 默认定义在原型上,不影响实例自身属性枚举性;若需私有字段,可搭配 #age 私有字段(需环境支持)。










