属性遮蔽指子对象自有属性覆盖原型同名属性,读取时优先返回自身值;赋值可新建或修改自有属性,hasownproperty()可判断是否被遮蔽,删除自有属性后遮蔽解除。

属性遮蔽(Property Shadowing)是 JavaScript 原型链中一个基础但关键的行为:当子对象自身拥有与原型上同名的属性时,读取该属性会优先返回子对象自己的值,不再继续向上查找原型——这个“盖住”原型属性的现象,就是遮蔽。
遮蔽只发生在读取时,但由写入触发
JavaScript 的属性访问机制默认从当前对象开始查找,找到第一个匹配就停止。所以只要子对象有了同名自有属性,无论原型上有没有、值是什么,都不会再用它。
- 给 不存在的属性赋值(如
obj.name = 'Alice'),会在obj上新建自有属性,从而遮蔽原型上的name - 给 已存在的自有属性赋值(如
obj.name = 'Bob'),只是修改自身值,不涉及原型 - 读取时永远按“自身 → 原型 → 原型的原型…”顺序,一旦自身有,就停住,不会跳过自身去取原型的
怎么判断一个属性是不是被遮蔽了
用 hasOwnProperty() 可以明确区分:它只检查对象自身的属性,不查原型链。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
-
obj.hasOwnProperty('name')返回true→ 属性在自身,可能遮蔽了原型 -
obj.hasOwnProperty('name')返回false但'name' in obj是true→ 属性来自原型,未被遮蔽 -
'name' in obj是false→ 原型链上都找不到
遮蔽不是错误,而是设计使然
这种机制让实例可以安全地覆盖继承来的默认值,而不会意外改写原型(也就是影响其他实例)。
- 比如多个
Person实例共享Person.prototype.species = 'Homo sapiens',但每个实例都可以设自己的name或age,互不干扰 - 删除自有属性(
delete obj.name)后,遮蔽解除,再次读取就会落到原型上 - 注意:对不可写属性(writable: false)赋值在严格模式下会报错,非严格模式下静默失败,也不会遮蔽
遮蔽效应不是 bug,是原型链查找规则自然产生的结果。理解它,才能准确预测属性从哪来、往哪写、删了之后行为怎么变。










