js 函数重载

54 阅读2分钟

js 函数重载

文件名称类型
main.js入口文件
jqueryRealize.jsjquery 实现逻辑
MyOverLoad.js更现代化的实现逻辑

代码里有详细解释

main.js

import jqueryRealize from './jqueryRealize.js'
import MyOverLoad from './MyOverLoad.js'


//第一种 jquery 写法
// 1.this指向 2.闭包 3.递归(接力棒)
const obj = {};

jqueryRealize(obj, 'realizeFun', (str) => {
    console.log("我是有1个形参的", this);
})
jqueryRealize(obj, 'realizeFun', () => {
    console.log("我是没有形参的");
})
jqueryRealize(obj, 'realizeFun', (str, str1) => {
    console.log("我是有2个形参的");
})
// 使用
obj.realizeFun(1) // 我是有1个形参的
obj.realizeFun() // 我是没有形参的
obj.realizeFun(1, 2) // 我是有2个形参的


// 第二种 更现代 写法
const overload = MyOverLoad();
overload.addCall('string', 'string', (str1, str2) => {
    console.log("我是两个字符串参数", str1, str2);
})
overload.addCall('string', (str1) => {
    console.log("我是一个字符串参数", str1);
})
overload.addCall('number', (num) => {
    console.log("我是一个数字参数", num);
})
overload('1', '2')
overload(1)
overload('1')

jqueryRealize.js

/**
 * 
 * @param {*} object 
 * @param {*} name 
 * @param {*} fun 
jqueryRealize(obj, 'realizeFun', (str) => {
     console.log("我是有1个形参的");
 })
 old = {}
 object[name] = function1
 jqueryRealize(obj, 'realizeFun', () => {
     console.log("我是没有形参的");
 })
     old = {funtion1(上一个旧的函数)}
 object[name] = function2 (这次新的函数)
 jqueryRealize(obj, 'realizeFun', (str, str1) => {
     console.log("我是有2个形参的");
 })
     old = {funtion2(上一个旧的函数)}
 object[name] = function3  (这次新的函数)
*/
const realizeReload = (object, name, fun) => {
    const old = object[name]
    // 覆盖上次数据(函数)
    object[name] = function (...args) {
        if (args.length === fun.length) { // 判断匹配成功
            return fun.apply(this, args) // 停止递归
        } else if (typeof old === 'function') {
            return old.apply(this, args)  // 上次旧的闭包 执行后形成接力棒(递归)
            // return 上次的函数 上次的数据 执行后不匹配->在递归
        }
    }
}
// 示例1:obj.realizeFun() //答案: 我是没有形参的
// 判断匹配失败 args.length === fun.length(0 === 1) -> 
// old === funtion {old(上个函数)}(递归)->
// 判断匹配成功 args.length === fun.length(0 === 0) -》
// 返回并执行 对应的函数 如无形参函数 匹配 无传参函数  

// 示例2:obj.realizeFun(1) // 我是有1个形参的
// 判断匹配成功 args.length === fun.length(1 === 1) -> 
// 返回并执行 对应的函数 如有一个形参函数 匹配 有一个传参函数  

export default realizeReload;

MyOverLoad.js

const MyOverLoad = () => {
    const map = new Map();
    function overload(...args) {
        // 转换成字符串
        const mapMark = args.map(item => typeof item).join(',');
        // console.log("mapMark", mapMark);
        const mapFn = map.get(mapMark);
        if (mapFn) { // 有这个函数 执行
            mapFn.apply(this, args);
        } else {
            throw new Error('没有对应的参数的函数')
        }
    }
    // 添加函数方法
    overload.addCall = (...args) => {
        const fn = args.pop();
        if (typeof fn !== 'function') {
            throw new Error('最后一个参数请是函数')
        }
        // 转换成字符串
        const mapMark = args.join(',')
        if (!map.get(mapMark)) {
            map.set(mapMark, fn)
        } else {
            console.warn('无需重复添加');
        }
    }
    return overload;
}
export default MyOverLoad