javascript原型链查找不检查属性描述符,只判断属性是否存在;查到后才由描述符控制赋值、枚举、删除等行为,遮蔽和冻结均不影响查找路径。

JavaScript 原型链查找过程本身不检查也不依赖属性描述符——它只认“属性是否存在”,不管该属性是 enumerable: false、writable: false 还是 configurable: false。描述符影响的是访问后的操作行为,而非查找路径或命中逻辑。
查找阶段完全忽略描述符
引擎执行属性读取(如 obj.x)时,严格按以下顺序走原型链:
- 先查
obj自身是否定义了x(无论enumerable是否为false,也无论configurable或writable如何) - 没找到就查
obj.__proto__,再查obj.__proto__.__proto__,直到null - 只要某一级对象上存在名为
x的自有属性(哪怕Object.getOwnPropertyDescriptor(obj, 'x')显示enumerable: false),查找立即终止并返回其值
描述符真正起作用的环节
一旦属性被查到,描述符才开始控制后续行为:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
value+writable: false→ 赋值语句(obj.x = ...)在严格模式下报错,非严格模式下静默失败 -
get/set→ 触发对应函数,而不是直接读/写内部存储 -
enumerable: false→ 不影响obj.x读取,但会让for...in和Object.keys()忽略它 -
configurable: false→ 禁止后续用Object.defineProperty修改描述符,也禁止delete obj.x
遮蔽(shadowing)与描述符的交互
实例上定义同名属性会屏蔽原型上的属性,这个过程同样无视描述符:
- 即使原型上
x是configurable: false的访问器,实例执行obj.x = 123仍会在自身创建一个数据属性x(除非原型访问器的set显式拒绝) - 若原型属性是
configurable: false且为访问器,而实例试图用Object.defineProperty(obj, 'x', {...})覆盖,则会失败(因为不可配置) - 但若原型属性是
configurable: true,实例覆盖后,原型上的原始定义就被永久遮蔽,无法自动恢复
冻结原型不影响查找,只限制修改
像 Object.freeze(Person.prototype) 这类操作,本质是把原型上所有自有属性设为 writable: false 和 configurable: false:
- 查找依然照常进行:
new Person().method()还是从Person.prototype找到方法 - 但你不能再给
Person.prototype新增属性,也不能改已有方法的实现或描述符 - 实例仍可添加自己的同名属性,从而遮蔽原型上的冻结属性
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










