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);