js 实现多态
多态的概念
多态是面向对象编程的核心特性之一,指同一操作作用于不同对象时产生不同的行为。JavaScript通过原型链和动态绑定实现多态,无需像Java等语言依赖严格的类继承体系。
基于原型链的多态实现
JavaScript中每个对象都有隐藏的[[Prototype]]属性(可通过__proto__或Object.getPrototypeOf()访问),当访问对象属性时,若当前对象不存在该属性,会沿原型链向上查找。

function Animal(name) {
this.name = name
}
Animal.prototype.speak = function() {
console.log(this.name + ' makes a noise.')
}
function Dog(name) {
Animal.call(this, name)
}
Dog.prototype = Object.create(Animal.prototype)
Dog.prototype.constructor = Dog
Dog.prototype.speak = function() {
console.log(this.name + ' barks.')
}
const animal = new Animal('Generic')
const dog = new Dog('Rex')
animal.speak() // 输出 "Generic makes a noise."
dog.speak() // 输出 "Rex barks."
基于鸭子类型的多态
JavaScript的弱类型特性允许"鸭子类型"(Duck Typing)实现多态:只要对象具有相同方法签名,即可视为同一类型。

class Car {
drive() {
console.log('Car is driving')
}
}
class Ship {
drive() {
console.log('Ship is sailing')
}
}
function operateVehicle(vehicle) {
vehicle.drive()
}
operateVehicle(new Car()) // 输出 "Car is driving"
operateVehicle(new Ship()) // 输出 "Ship is sailing"
使用Symbol实现多态
ES6的Symbol可以创建唯一属性键,避免属性名冲突,实现更安全的多态。
const move = Symbol('move')
class Bird {
[move]() {
console.log('Flying in the sky')
}
}
class Fish {
[move]() {
console.log('Swimming in water')
}
}
function animate(creature) {
creature[move]()
}
animate(new Bird()) // 输出 "Flying in the sky"
animate(new Fish()) // 输出 "Swimming in water"
多态与高阶函数结合
通过函数作为参数传递,可以实现更灵活的多态行为。
function stringProcessor(str, processor) {
return processor(str)
}
const upperProcessor = str => str.toUpperCase()
const reverseProcessor = str => [...str].reverse().join('')
console.log(stringProcessor('hello', upperProcessor)) // 输出 "HELLO"
console.log(stringProcessor('hello', reverseProcessor)) // 输出 "olleh"
注意事项
- JavaScript的多态是运行时绑定(动态绑定),与编译时绑定的静态语言不同
- 过度使用鸭子类型可能导致代码难以维护,建议结合TypeScript等工具进行类型约束
- 原型链修改会影响所有实例,需谨慎操作






