属性遮蔽不是覆盖原型,而是属性查找时的优先级短路:先查自身,命中即止,原型属性仍完好;赋值默认新建自有属性,delete仅移除自身属性,之后访问自然回退到原型。

属性屏蔽不是“覆盖原型”,而是访问时的查找优先级短路:只要对象自身有同名属性,引擎就不再往上找原型链。
屏蔽的本质是查找顺序,不是修改原型
JavaScript 访问属性始终按固定路径执行:
- 先查对象自身(own property)
- 没找到才沿 [[Prototype]] 向上逐层查找
- 一旦在某一层命中,立即返回,不继续向上
所谓“屏蔽”,只是因为查找在第一步就结束了。原型上的属性依然完好无损,只是被跳过了。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
赋值和删除行为印证屏蔽逻辑
对 obj.x = val 的处理完全取决于 obj 自身是否已有 x:
- 若
obj自身没有x,且原型链上存在可写x,赋值仍会把x新增到obj自身(触发屏蔽) - 若
obj自身已有x,赋值只改它,原型不受影响 -
delete obj.x只删自身属性;删完再读obj.x,就会自然落到原型上,显出“继承恢复”效果
方法与访问器的屏蔽差异需特别注意
普通方法和数据属性屏蔽规则一致,但访问器(getter/setter)例外:
- 若原型上定义了
get x(),直接写obj.x = 123不会新建自有属性,而可能触发原型的 setter - 要真正屏蔽访问器,必须在自身用
Object.defineProperty显式定义同名 get/set - 否则看似“赋值”,实际是委托给原型处理,不是屏蔽
如何准确判断一个属性是否被屏蔽?
别用 in 或 obj.x === undefined,它们无法区分“未定义”和“值为 undefined”:
- ✅ 正确方式:
obj.hasOwnProperty('x')—— 返回true表示自有属性,即已屏蔽 - ✅ 辅助验证:
obj.__proto__.hasOwnProperty('x')看原型是否原本就有 - ❌
'x' in obj会返回true即使x来自原型,无法识别屏蔽
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










