es6 class 的 getter/setter 通过在原型上定义访问器属性拦截读写操作,访问已声明属性名时自动触发对应函数;需避免同名属性递归调用,推荐用私有字段(如#name)存储值;可拦截明确定义的属性读写及原型共享逻辑,但无法拦截未定义或动态新增属性。

ES6 Class 的 getter 和 setter 通过在原型上定义访问器属性来拦截读写操作——访问 已声明的属性名 时自动触发对应函数,调用者无需感知底层逻辑。
拦截机制:不是钩子,而是属性描述符
getter/setter 不是运行时插入的监听器,而是在类定义阶段就写入 MyClass.prototype 的属性描述符中:
- 写
get name() { ... },等价于在原型上为name属性设置get函数 - 每次执行
inst.name或inst.name = 'x',JS 引擎查到该描述符,直接执行对应函数 - 它们属于“自有访问器属性”,可被
Object.keys()、for...in枚举
必须避开的两个死循环陷阱
getter 和 setter 内部若操作同名属性,会再次触发自身,导致无限递归报错(RangeError):
用于 inference.sh 的 JavaScript/TypeScript SDK,可运行 AI 应用、构建代理、集成 150+ 模型。包名:@inferencesh/sdk(npm install),完整 TypeScript 支持。
-
错误写法:
get name() { return this.name; }或set name(v) { this.name = v; } -
正确做法:用私有字段(如
#name)或约定命名的内部字段(如_name)存储真实值 - 推荐优先使用私有字段:
#name = '';在类体顶部声明,setter 中赋值this.#name = value,getter 中返回this.#name
典型拦截场景与实用写法
拦截的核心价值在于把业务逻辑自然嵌入属性操作中,而非单纯“挡一下”:
-
数据校验:在 setter 中检查类型、范围,非法值直接
throw或静默处理 -
自动转换:比如将字符串
age转为数字再判断是否有效,避免调用方重复处理 - 副作用触发:赋值后自动更新关联状态、记录日志、通知视图刷新
-
计算属性封装:get 中返回基于其他字段运算的结果,例如
get fullName() { return this.firstName + ' ' + this.lastName; }
它能拦什么,不能拦什么
理解边界才能合理使用:
-
✅ 能拦截:对类中明确定义了 getter/setter 的属性名(如
inst.age)的读写 - ✅ 能拦截:该属性在原型上的存在性,因此所有实例共享同一套拦截逻辑
-
❌ 不能拦截:未定义的属性(如
inst.unknown),不会触发任何访问器 - ❌ 不能拦截:动态新增的属性(除非提前在类中声明好对应的 getter/setter)










