javascript 中实例对象通过自身属性遮蔽(shadowing)原型链上的同名属性来实现覆盖。具体做法是直接在实例上赋值该属性,例如 instance.prop = value,此时访问该属性时会优先返回实例自身的值,而不会查找原型。

如何验证实例是否成功覆盖了原型属性
可以通过 hasOwnProperty() 方法或 in 操作符来验证。如果 instance.hasOwnProperty('prop') 返回 true,说明属性存在于实例自身而非原型中;而 'prop' in instance 始终返回 true,因为它会检查原型链。

function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
return 'Hello, I am ' + this.name;
};
const alice = new Person('Alice');
console.log(alice.hasOwnProperty('greet')); // false
console.log('greet' in alice); // true
// 覆盖原型方法
alice.greet = function() {
return 'Hi, I am ' + this.name;
};
console.log(alice.hasOwnProperty('greet')); // true
console.log(alice.greet()); // Hi, I am Alice
使用 Object.defineProperty 进行更精细的控制
除了直接赋值,还可以使用 Object.defineProperty() 在实例上定义属性,这样可以控制属性的可枚举性、可写性等特征。这种方式同样会创建实例自身的属性,从而遮蔽原型中的同名属性。

function Car(model) {
this.model = model;
}
Car.prototype.start = function() {
return this.model + ' is starting';
};
const myCar = new Car('Toyota');
// 使用 defineProperty 覆盖
Object.defineProperty(myCar, 'start', {
value: function() {
return this.model + ' is silently starting';
},
writable: true,
enumerable: false,
configurable: true
});
console.log(myCar.hasOwnProperty('start')); // true
console.log(myCar.start()); // Toyota is silently starting
基于程序中某个输入、条件或结果的具体问题
当原型链中存在多个层级的同名属性时,实例上的赋值只会遮蔽最近的原型属性,而不会影响更高层级的原型属性。这意味着如果修改了原型链中间层的属性,实例仍然可以访问到更高层级的原型属性,除非实例也对该属性进行了赋值。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











