在 JavaScript 中,传统的面向对象语言中的函数重载(Overloading)概念并不直接支持,即不能在同一作用域内定义多个同名函数,根据传入参数的数量或类型来调用不同的实现。然而,可以通过一些技巧模拟出类似的效果:
模拟函数重载
1. 基于参数个数
利用arguments
对象检测传入的参数数量,并在函数内部进行不同的处理。
function calculate() {
switch (arguments.length) {
case 1:
return arguments[0] * arguments[0];
case 2:
return arguments[0] + arguments[1];
// 更多情况...
default:
throw new Error('Invalid number of arguments');
}
}
console.log(calculate(3)); // 输出9
console.log(calculate(1, 2)); // 输出3
2. 基于参数类型
需要在函数内部检查传入参数的具体类型,然后执行相应的逻辑。
function process(data) {
if (typeof data === 'string') {
// 处理字符串
} else if (Array.isArray(data)) {
// 处理数组
} else if (data instanceof MyCustomType) {
// 处理自定义类型的实例
} else {
throw new TypeError('Unsupported argument type');
}
}
JavaScript 中的多态
在 JavaScript 中,多态是通过原型链和构造函数继承机制以及“鸭子类型”(duck typing)实现的。这意味着一个接口可以被不同类的对象实现,这些对象在运行时表现出来的行为可能会有所不同。
1. 原型链与方法重写(Override)
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function () {
console.log('Animal makes a sound');
};
function Dog(name) {
Animal.call(this, name); // 继承Animal
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
// 重写父类方法
Dog.prototype.speak = function () {
console.log('Dog barks');
};
let myDog = new Dog('Rex');
myDog.speak(); // 输出 "Dog barks"
2. 鸭子类型(动态多态)
function canSwim(animal) {
if (animal.swim) {
animal.swim();
} else {
console.log('This animal cannot swim');
}
}
let fish = { swim: () => console.log('Fish is swimming') };
let dog = { bark: () => console.log('Dog barks') };
canSwim(fish); // 输出 "Fish is swimming"
canSwim(dog); // 输出 "This animal cannot swim"
在这个例子中,canSwim
函数不会关心对象的具体类型,只要它具有 swim
方法,就会调用该方法,实现了多态行为。