JavaScript原型链同名方法调用遵循属性查找顺序:先查实例自身,再沿__proto__逐级向上,找到首个匹配即执行;实例属性会完全遮蔽原型链上所有同名方法。

JavaScript 原型链处理同名方法时,不比较“谁更权威”或“谁定义得早”,而是严格按属性查找顺序执行:先查实例自身,再沿 __proto__ 一级级向上,找到第一个匹配就停止。这个“第一个”,就是实际被调用的方法。
查找路径决定优先级
访问 obj.method() 时,引擎执行以下步骤:
- 检查
obj自身是否有method属性(自有属性);有则直接调用,不继续查找 - 若无,转向
obj.__proto__(即构造函数的prototype),查该对象上是否有method - 若仍无,继续查
obj.__proto__.__proto__,依此类推 - 直到找到,或抵达
Object.prototype后的null,返回undefined
实例属性永远遮蔽原型方法
如果在实例上直接赋值了同名方法或字段,它会完全屏蔽原型链上的所有同名方法——哪怕父类、祖父类都定义了,也根本不会被访问到。
-
obj.say = function() { console.log('instance'); };→ 调用obj.say()总是执行这个 - 即使
obj.__proto__.say = function() { console.log('proto'); }存在,也不会触发 - 可用
obj.hasOwnProperty('say')判断是否为自有属性
子类方法覆盖父类方法的本质
在 class B extends A 中,B.prototype.method 覆盖 A.prototype.method,不是因为“子类更高”,而是因为原型链中 B.prototype 在 A.prototype 之前被查到。
立即学习“Java免费学习笔记(深入)”;
- 实例
new B()的原型链是:B.prototype → A.prototype → Object.prototype - 当
B.prototype上有method,引擎在第二步就命中,不再继续往下找 - 这和书写顺序无关,只取决于该方法是否存在于当前正在查找的那层对象上
静态方法与实例方法互不干扰
静态方法(static method())存在类本身(即构造函数)上,而实例方法在 prototype 上。它们位于不同查找路径,不存在覆盖关系。
-
B.method()查的是B对象自身(B.__proto__指向A,用于继承静态方法) -
new B().method()查的是B.prototype及其上游 - 即使名字相同,两者完全独立,不会互相遮蔽


















