通过getter与setter可构建受控类属性:setter拦截赋值实现校验(如年龄0–150),getter封装派生逻辑避免冗余计算(如邮箱用户名),私有字段+只getter实现伪只读,proxy则适用于批量属性统一拦截。

通过 getter 与 setter 构建受控类属性,核心在于把属性访问“拦截下来”,在读取和赋值时插入逻辑控制——比如校验、转换、触发响应、缓存计算等,让属性行为更可预测、更易维护。
用 setter 拦截赋值,实现数据约束
setter 不只是赋值通道,更是校验入口。比如限制年龄只能是 0–150 的整数:
class Person {
#age = 0;
get age() { return this.#age; }
set age(value) {
if (!Number.isInteger(value) || value 150) {
throw new Error('年龄必须是 0–150 的整数');
}
this.#age = value;
}
}
这样每次 person.age = -5 都会立刻报错,而不是等到业务逻辑里才发现异常。
用 getter 封装派生逻辑,避免冗余计算
当属性依赖其他字段且计算开销较大时,getter 可以按需计算、延迟求值。例如邮箱用户名(@前部分):
- 直接暴露
email字段,但提供只读的username属性 - getter 内部做字符串切分,不预先存储,也不在构造时重复计算
- 若 email 为空或无 @,返回空字符串,逻辑集中、调用方无感
这样既保持接口简洁,又避免了提前计算或缓存失效问题。
组合私有字段 + 存取器,实现“伪只读”与受控更新
JavaScript 没有真正的私有只读属性,但可以用 #field 私有字段 + 只有 getter 的存取器模拟:
class Config {
#timeout = 5000;
get timeout() { return this.#timeout; }
// 没有 setter → 外部无法修改
updateTimeout(ms) {
if (ms > 0) this.#timeout = ms;
}
}
外部只能读 config.timeout,修改必须走 updateTimeout() 方法——把变更路径收口,便于打日志、加权限、触发更新通知。
搭配 Proxy 进阶:统一拦截多个属性
当类中大量属性都需要类似校验或响应逻辑时,逐个写 getter/setter 易重复。此时可用 Proxy 在实例层面统一拦截:
- 代理对象的
get和set陷阱,自动识别字段名并执行通用规则 - 结合 Symbol 或约定前缀(如
_valid)区分受控字段 - 适合配置类、表单模型等需要批量约束的场景
注意 Proxy 会带来轻微性能开销,小规模类推荐原生存取器;大规模动态属性才考虑 Proxy 统一治理。











