JavaScript中getter/setter通过原型链动态委托实现,不被继承也不复制;子对象未定义同名访问器时自动委托执行,定义后则遮蔽原型逻辑;class语法支持super复用父逻辑,防范意外遮蔽需结合校验、writable:false等策略。

JavaScript 中 getter 与 setter 在原型链上不是被“继承”过来的属性,而是通过动态委托实现访问控制——每次读写时,引擎沿原型链查找并执行对应函数。理解这一点,是避免常见逻辑失效的关键。
访问器走委托,不复制也不拥有
原型上的 getter/setter 不会出现在子对象自身属性中,也不会被拷贝到实例上。只要子对象没定义同名访问器,所有访问都自动委托给原型函数执行。
- 父类原型定义
get fullName()→ 子实例调用obj.fullName就触发它 - 子对象未定义任何访问器 → 完全依赖原型逻辑,无额外开销
- 用
Object.getPrototypeOf(obj)查看原型,能看到访问器定义;但Object.keys(obj)或for...in不会列出它们
遮蔽规则决定行为走向
子对象一旦定义同名属性(无论数据属性还是访问器),就会中断委托链。遮蔽方式不同,结果差异明显:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 只写
obj.fullName = "Alice"(且父类无 setter)→ 在 obj 自身创建数据属性,后续读取直接返回字符串,不再触发 getter - 只定义
set fullName(v),不定义get fullName→ 写入有效,读取返回undefined - 同时定义 get 和 set → 完全覆盖原型行为,可完全自控
class 语法让委托更可控
ES6 class 声明的访问器默认 configurable: true,支持安全重写,并提供 super 显式复用父逻辑:
立即学习“Java免费学习笔记(深入)”;
- 子类不重写时,自动沿 [[Prototype]] 查找父类访问器
- 重写后可用
super.fullName(注意不是super.fullName())读取父级计算值 - 例如:
set name(v) { super.name = v.trim(); }既复用父逻辑,又增加预处理
防范意外遮蔽的实用做法
父类用 getter 控制状态时,子对象直接赋值极易破坏逻辑。几种防御方式可组合使用:
- 为关键属性提供配套 setter,并在校验失败时抛错(如非空、格式校验)
- 用
Object.defineProperty在原型上设writable: false,阻止数据属性覆盖 - 若需彻底禁止修改,设
configurable: false(注意:之后无法重定义) - 避免混用:同一属性名不要在原型用 getter,在实例又手动赋值

















