js 实现多态
多态的概念
多态是面向对象编程的三大特性之一(封装、继承、多态),指同一操作作用于不同对象时会产生不同的行为。在JavaScript中,由于是动态类型语言,多态的实现方式与静态类型语言(如Java/C++)有所不同。
基于原型链的多态实现
JavaScript通过原型链实现继承,多态的表现形式为子类可以覆盖父类的方法:
class Animal {
makeSound() {
console.log('Some generic animal sound');
}
}
class Dog extends Animal {
makeSound() {
console.log('Bark!');
}
}
class Cat extends Animal {
makeSound() {
console.log('Meow!');
}
}
const animals = [new Animal(), new Dog(), new Cat()];
animals.forEach(animal => animal.makeSound());
// 输出:
// Some generic animal sound
// Bark!
// Meow!
基于鸭子类型的多态
JavaScript不检查对象类型,而是关注对象是否具有所需的方法或属性("如果它走起来像鸭子,叫起来像鸭子,那么它就是鸭子"):
function makeSound(animal) {
if (animal && typeof animal.sound === 'function') {
animal.sound();
}
}
const duck = {
sound: () => console.log('Quack!')
};
const robot = {
sound: () => console.log('Beep boop!')
};
makeSound(duck); // Quack!
makeSound(robot); // Beep boop!
通过参数多态实现
利用JavaScript的动态类型特性,函数可以根据传入参数的不同类型表现不同行为:
function calculateArea(shape) {
if (shape.type === 'circle') {
return Math.PI * shape.radius 2;
} else if (shape.type === 'rectangle') {
return shape.width * shape.height;
}
}
console.log(calculateArea({ type: 'circle', radius: 5 })); // 78.5398...
console.log(calculateArea({ type: 'rectangle', width: 4, height: 6 })); // 24
使用Symbol实现多态
ES6的Symbol可以创建唯一属性键,实现更安全的多态:
const soundSymbol = Symbol('sound');
class Bird {
[soundSymbol]() {
console.log('Chirp!');
}
}
class Helicopter {
[soundSymbol]() {
console.log('Whirr!');
}
}
function playSound(entity) {
if (entity[soundSymbol]) {
entity[soundSymbol]();
}
}
playSound(new Bird()); // Chirp!
playSound(new Helicopter()); // Whirr!
多态的实际应用场景
- 插件系统:不同插件实现相同接口方法
- UI组件:不同组件实现相同的render方法
- 中间件模式:多个中间件实现相同的处理接口
- 游戏开发:不同游戏对象实现相同的update/draw方法
JavaScript的多态实现更加灵活,不需要显式接口定义,只需对象具有相应的方法或属性即可实现多态行为。这种动态特性使得代码更易于扩展和维护。







