JavaScript中的多态性依托原型继承和动态方法查找实现,表现为同一方法名根据对象实际原型链自动执行对应版本;它依赖继承结构,也支持鸭子类型带来的广义多态。

JS 中的多态性不是靠编译时检查或类型约束实现的,而是依托原型继承 + 动态方法查找天然形成的。它体现在:**同一方法名,调用时根据对象实际的原型链结构,自动找到并执行对应版本的实现**。
多态依赖继承结构
没有继承,就谈不上“统一接口、不同实现”。JavaScript 中,多态通常发生在子类继承父类后重写(覆盖)某个方法的场景:
- 父类定义通用方法签名(比如 speak()),作为行为契约
- 子类通过在自身 prototype 上定义同名方法,提供具体逻辑
- 实例调用该方法时,引擎沿原型链向上查找,优先使用最近一层的定义
运行时动态绑定是关键
JS 不在声明时决定调用哪个方法,而是在每次 执行时才确定。例如:
const animal = new Animal();const dog = new Dog();
const cat = new Cat();
animal.speak(); // 走 Animal.prototype.speak
dog.speak(); // 走 Dog.prototype.speak(即使 Dog 没显式写 class,只要 prototype 上有同名方法)
cat.speak(); // 走 Cat.prototype.speak
不依赖 class 语法也能多态
ES6 的 class/extends 只是语法糖,底层仍是原型操作。哪怕用函数构造器+手动设置 prototype,只要满足:
- 子类实例的 __proto__ 链最终指向父类 prototype
- 子类 prototype 上存在与父类同名的方法
就能触发多态行为。比如传统写法中:
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
Parent.prototype.speak = function() { return '发出声音'; };
那么 new Child().speak() 就不会调用 Parent 的版本。
鸭子类型让多态更宽泛
严格来说,JS 多态不限于继承体系内——只要多个对象都有 speak 方法,函数就可以统一接收并调用:
function makeItSpeak(obj) { obj.speak(); }makeItSpeak({ speak: () => '嘎嘎!' });
makeItSpeak(new Dog());
makeItSpeak({ speak: () => '叮咚!' });
这种基于“有没有该方法”而非“是不是某类实例”的机制,就是鸭子类型支撑的广义多态,比经典 OOP 更灵活,也更贴近 JS 的本质。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










