JavaScript 中的 getter 和 setter 是通过定义访问器属性来拦截属性读写行为的机制,支持对象字面量和 Object.defineProperty() 两种定义方式,适用于数据校验、计算属性、副作用触发等场景,并需注意 this 指向与私有存储方案,其作用范围限于预定义属性,而 Proxy 可代理整个对象并拦截动态属性及更多操作。

JavaScript 中的 getter 和 setter 是一种在不改变对象使用方式的前提下,对属性读取和赋值行为进行拦截与控制的机制。它们不是“劫持”属性本身,而是通过定义访问器属性(accessor property),覆盖默认的数据属性(data property)行为,从而实现对属性访问逻辑的自定义。
getter 与 setter 的基本写法
可以通过对象字面量或 Object.defineProperty() 两种方式定义:
- 对象字面量中用 get 和 set 关键字声明访问器属性,不能同时存在同名的 value/writable 或 get/set 混用;
-
Object.defineProperty() 更灵活,支持在已有对象上动态添加或修改访问器属性,且可精确控制
configurable和enumerable等特性。
如何用 getter/setter 实现属性访问控制
常见用途包括:数据校验、格式转换、依赖追踪、日志记录等。例如:
- 在 setter 中检查赋值是否为合法类型或范围,非法时抛出错误或静默修正;
- 在 getter 中返回计算值(如
fullName基于firstName和lastName拼接),避免重复计算可配合缓存; - setter 触发副作用,比如更新 DOM、通知观察者、触发事件等。
注意 this 指向与内部存储
getter/setter 中的 this 指向当前对象(调用时的上下文),但需避免直接用同名属性递归调用自身。正确做法是使用私有命名(如 _value)或 WeakMap 存储原始值:
立即学习“Java免费学习笔记(深入)”;
- 用下划线前缀(如
_age)是常见约定,但不真正私有; - 用 WeakMap 可实现真正的私有状态封装,适合构造函数或类中多个实例隔离数据。
与 Proxy 的区别:适用场景不同
getter/setter 作用于**单个属性**,需提前定义;Proxy 则可代理整个对象,支持对任意属性(包括动态新增的)统一拦截,能力更强但开销略大。若只需控制几个关键字段,用 getter/setter 更轻量直观;若需全局拦截、属性不存在时兜底、或拦截 in / delete / enumerate 等操作,应选 Proxy。










