javascript中属性查找与描述符机制分离:查找走原型链判断存在性,不关心描述符;描述符仅控制访问细节(如可枚举、可写、可配置),遮蔽由实例同名属性触发,与描述符无关。

JavaScript 中属性查找和属性描述符不是同一层机制,不存在“优先级竞争”。属性查找走的是原型链路径,而描述符控制的是属性本身的可访问性细节——两者分工明确,协同工作。
属性查找只看“有没有”,不看“怎么定义”
引擎访问 obj.prop 时,只关心:当前对象或其原型链上是否存在名为 prop 的自有属性。只要存在(哪怕 enumerable: false、configurable: false 或 writable: false),就能读取到值。
- 不可枚举属性(
enumerable: false)仍能被直接访问,只是不会出现在for...in或Object.keys()中 - 只读属性(
writable: false)可以读,赋值在非严格模式下静默失败,严格模式下抛TypeError - 不可配置属性(
configurable: false)不能被delete,也不能改描述符,但不影响查找过程
遮蔽(shadowing)发生在查找阶段,与描述符无关
当实例自身添加了同名属性,无论该属性是用 this.x =、Object.defineProperty 还是字面量定义的,都会立即中断原型链查找——引擎不再继续向上找,哪怕原型上的同名属性有更宽松的描述符(比如可写、可配置)。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
-
delete obj.prop删除实例属性后,原型链上的同名属性才重新暴露出来 - 给实例设
writable: false的同名属性,依然会遮蔽原型上writable: true的属性 - 遮蔽是查找逻辑的自然结果,不是描述符触发的行为
枚举行为和查找行为必须分开理解
for...in、Object.keys()、JSON.stringify() 等操作受 enumerable 控制,但它们不参与属性查找;而 obj.prop、obj.hasOwnProperty('prop')、'prop' in obj 这些才是真正的查找相关操作。
-
hasOwnProperty只判断是否为实例自有属性,不管enumerable状态 -
in操作符返回true只要属性存在于实例或原型链任一环节,也不管是否可枚举 - 想确认某个属性是否来自原型而非实例?可用
!obj.hasOwnProperty('prop') && 'prop' in obj
静态方法查的是函数自身的 __proto__ 链
类的静态方法(class A { static foo() {} })不属于实例原型链,而是挂在构造函数上,查找路径是:A → A.__proto__(即 Function.prototype)→ Object.prototype → null。
- 这和实例方法(
A.prototype.foo)的查找路径完全分离 - 静态属性同样遵循遮蔽规则:若
A.foo = ...,则覆盖Function.prototype上同名属性 - 不要误以为
A.foo()会去查A.prototype.foo,那是实例方法的路径
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










