js 函数重载 override/overloading/createOverload
JavaScript中的函数重载(Function overloading)
场景
一个多种方式调用的
getUsers实现。已经添加到 next@1.1.12 中
nx.createOverload方法

通常实现
即通常我们没有
createOveride的实现方式,非优雅的实现。
function getUsers(...args) {
  const len = args.length;
  const types = args.map((item) => typeof item).join();
  switch (true) {
    // get by id
    case len === 1 && types === 'number':
      console.log('get by id');
      break;
    case len === 1 && types === 'string':
      console.log('get by name');
      break;
    case len === 2 && types === 'string,number':
      console.log('get by name and age');
      break;
    default:
      console.log('get all');
  }
}推荐
一种更优雅、通用的写法
function createOverload() {
  const callMap = {};
  function overload(...args) {
    const key = args.map((item) => typeof item).join();
    const fn = callMap[key];
    if (!fn) throw new Error('没有匹配的函数');
    return fn(...args);
  }
  overload.add = function (...args) {
    const fn = args.pop();
    const types = args.join();
    if (typeof fn !== 'function') {
      throw new Error('最后一个参数必须是函数');
    }
    callMap[types] = fn;
  };
  return overload;
}
const getUsers = createOverload();
getUsers.add('number', function (id) {
  console.log('get by id');
});
getUsers.add('string', function (name) {
  console.log('get by name');
});
getUsers.add('string,number', function (name, age) {
  console.log('get by name and age');
});
getUsers.add('', function () {
  console.log('get all');
});
getUsers();
getUsers(1);
getUsers('1');
getUsers('1', 1);优化
- 优化报错
- 优化 add方法时候传参
function createOverload() {
  const callMap = {};
  function overload(...args) {
    const key = args.map((item) => typeof item).join();
    const fn = callMap[key];
    if (!fn) {
      throw new Error(`没有匹配的函数,参数类型: [${key}]`);
    }
    return fn(...args);
  }
  overload.add = ({ args, fn }) => {
    if (typeof fn !== 'function') {
      throw new Error('最后一个参数必须是函数');
    }
    const types = args.join();
    callMap[types] = fn;
  };
  return overload;
}
const getUsers = createOverload();
getUsers.add({
  args: [],
  fn: function () {
    console.log('get all');
  }
});
getUsers.add({
  args: ['number'],
  fn: function (id) {
    console.log('get by id');
  }
});
getUsers.add({
  args: ['string'],
  fn: function (name) {
    console.log('get by name');
  }
});
getUsers.add({
  args: ['string', 'number'],
  fn: function (name, age) {
    console.log('get by name and age');
  }
});
getUsers(); 				// get all
getUsers(1); 				// get by id
getUsers('tom'); 			// get by name
getUsers('tom', 18); 		// get by name and age实战
重构
keyMap方法
const nx = require('@jswork/next');
const keyMap = nx.createOverload();
// 只有一个参数,并且参数为 array
keyMap.add({
  args: ['array'],
  fn: function (inArray) {
    return inArray.map((item) => {
      return { value: item, label: item };
    });
  }
});
// 将目标重构为2个array的情况
keyMap.add({
  args: ['array', 'array'],
  fn: function (inArray1, inArray2) {
    return inArray1.map((item) => {
      return inArray2.reduce((acc, key, index) => {
        acc[key] = item;
        return acc;
      }, {});
    });
  }
});
keyMap.add({
  args: ['object', 'object'],
  fn: function (inTarget, inObject) {
    return Object.keys(inObject).reduce((acc, key) => {
      acc[inObject[key]] = inTarget[key];
      return acc;
    }, {});
  }
});
const rs1 = keyMap(['a', 'b', 'c']);
const rs2 = keyMap(['a', 'b', 'c'], ['id', 'code', 'key']);
const rs3 = keyMap(
  {
    name: 'afei',
    email: 'afei@js.work'
  },
  {
    name: 'value',
    email: 'label'
  }
);
//... 更多的实现
console.log(rs3);