重载方法在JS和TS中的实现

40 阅读2分钟

JS

arguments 是一个对应于传递给函数的参数的类数组对象。Arguments对象介绍传送门

可以使用js方法的参数类数组对象arguments进行自动匹配

  • 判断方法的入参个数和类型
  • 根据不同的个数和类型执行不同的分支
  • 具体实现如下:
/**
 * 1个参数:返回乘方
 * 2个参数:返回第一个参数的x次方,x为第2个参数
 * 3个参数:返回前面两个数相乘后的x次方,x为第3个参数
 * 超过3个参数:返回所有参数的乘积
 */
function multiplication() {
  const length = arguments.length;
  if (length === 0) return NaN;
  
  let check = true;
  [...arguments].forEach(ele => {
    if (typeof ele !== 'number') {
      check = false;
    }
  });
  if (!check) {
    return NaN;
  }

  switch (length) {
    case 1:
      return arguments[0] ** 2;
    case 2:
      return arguments[0] ** arguments[1];
    case 3:
      return (arguments[0] * arguments[1]) ** arguments[2];
    default:
      return [...arguments].reduce((pre, cur) => pre * cur);
  }
}

// 使用
console.log(multiplication(2));          // log: 4
console.log(multiplication(2, 4));       // log: 16
console.log(multiplication(2, 4, 2));    // log: 64
console.log(multiplication(2, 4, 2, 4)); // log: 80
  • 如有需要,甚至可以像css那样不用控制参数传入的顺序,而是根据传入参数的类型进行匹配
/**
 * 将传入的字符串重复x次返回,x为传入的数字
 * 限定:必须且只能传入一个字符串,数字不传代表重复一次
 */
function repeatString() {
  if (arguments) { }
  const length = arguments.length;
  if (length === 0 || length > 2) throw '参数错误';

  if ((length === 1 && typeof arguments[0] !== 'string') ||
    (length === 2 && typeof arguments[0] !== 'string' && typeof arguments[1] !== 'string')) {
    throw '请传入字符串';
  }

  if (typeof arguments[0] === 'string') {
    return arguments[0].repeat(arguments[1] ?? 1);
  } else {
    return arguments[1].repeat(arguments[0]);
  }
}

// 使用
console.log(repeatString());          // error: 参数错误
console.log(repeatString(2, 'a', 4)); // error: 参数错误
console.log(repeatString(1));         // error: 请传入字符串
console.log(repeatString(1, 3));      // error: 请传入字符串
console.log(repeatString('a'));       // log: a
console.log(repeatString('a', 3));    // log: aaa
console.log(repeatString(4, 'a'));    // log: aaaa

TS

  • TS原生支持方法重载
  • 参考mockjs中的now方法实现
interface MockjsRandomDate {
    ...
    now(util: RandomDateUtilString, format?: S): S;
    now(format?: S): S;
}

// 使用now方法
MockJS.Random.now('day', 'yyyy-MM-dd HH:mm:ss');
MockJS.Random.now('yyyy-MM-dd HH:mm:ss');

PS:如果有需要补充的内容,请在评论区留言

转载时请注明“来自掘金 - EvenZhu”