实现函数重载和多态

2024-02-06  本文已影响0人  Max_Law

在 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 方法,就会调用该方法,实现了多态行为。

上一篇 下一篇

猜你喜欢

热点阅读