原型链中的属性遮蔽是指当实例对象自身存在某个属性时,该属性会优先于原型链上同名的属性被访问到。要理解这一点,只需在实例上直接定义同名属性,即可覆盖原型上的值,后续读取将始终返回实例自身的属性。

Object.create() 创建的对象如何体现遮蔽
使用 Object.create() 可以创建一个以特定对象为原型的空对象。如果在创建后向该实例添加与原型同名的属性,就会立即发生遮蔽。例如,原型上有 name 属性,实例上也设置 name,读取实例的 name 将得到实例的值,而原型上的值被“遮蔽”不可见。

const parent = { name: 'Parent' };
const child = Object.create(parent);
console.log(child.name); // 'Parent'
child.name = 'Child';
console.log(child.name); // 'Child'
上述代码中,第一行输出原型值,第二行输出实例值。这展示了遮蔽发生的瞬间变化。
立即学习“Java免费学习笔记(深入)”;
掌握 ES6+ 特性,包括 async/await、解构、扩展运算符、箭头函数、Promise、模块、迭代器、生成器以及函数式编程模式,编写简洁高效的 Java
通过 hasOwnProperty 检测遮蔽状态
判断一个属性是否被遮蔽,可以使用 hasOwnProperty 方法。如果该方法返回 true,说明属性存在于实例自身,即发生了遮蔽;如果返回 false,说明属性来自原型链。结合 in 操作符,可以全面检查属性的存在性。

const obj = { prop: 'own' };
const proto = { prop: 'proto' };
const instance = Object.create(proto);
instance.prop = 'shadowed';
console.log(instance.hasOwnProperty('prop')); // true
console.log('prop' in instance); // true
console.log(proto.hasOwnProperty('prop')); // true
这里 instance 的 prop 被遮蔽,hasOwnProperty 确认了这一点。而 proto 自身的 prop 依然存在,只是对 instance 不可见。
修改原型属性对已遮蔽实例的影响
当实例属性已经遮蔽了原型属性后,修改原型上的同名属性不会影响实例的读取结果。因为 JavaScript 引擎在查找属性时,一旦在实例层找到,就会停止搜索原型链。因此,遮蔽后的实例属性与原型属性完全独立。

















