JS 实现函数重载

122 阅读1分钟

问题

在默认的 JS 中,并不支持函数重载,

如果要实现该功能,需要在同一个函数内对输入的参数个数类型依次判断,

业务一复杂代码就会很冗长

function getUser(...args){
    if(args.length===0){
        console.log('得到所有用户')
    }else if( args.length===1){
        if(typeof args[0] === "string"){
            console.log('按照名字查询')
        }else if(typeof args[0] === "number"){
            console.log('按照页码查询')
        }
    }else if( args.length===2){
        // xxxxx
    }
}


getUsers(); //得到所有用户
getUsers(1); // 得到第一页的用户,默认10个
getUsers(1,20); // 得到第一页的20个用户
getUsers('张'); //查找姓名包含张的用户
getUsers('张','男'); //查找姓名为张且性别为男的用户

修改策略

创建overload.js

function createOverload(){
    function overload(...args){
        const key = args.map((arg)=> typeof arg).join(',')
        const fn = callMap.get(key)
        if(fn){
            return fn.apply(this,args)
        }
        throw new Error("no matching function")
    }
    const callMap = new Map()
    overload.addImpl = function(...args){
        const fn = args.pop()
        if(!fn || typeof  fn!== 'function'){
            return
        }
        const types = args
        callMap.set(types.join(','),fn)

    }
    return overload
}

export default createOverload

创建重载方法并调用

import createOverload from './overload.js'
const getUsers = createOverload()

getUsers.addImpl(()=>{
    console.log("查询所有用户")
})

const searchPage = (page,size=10) =>{
    console.log("按照页面和数量查询用户")
}

getUsers.addImpl('number',searchPage)
getUsers.addImpl('number','number',searchPage)

getUsers.addImpl('string',(name)=>{
    console.log('按照用户名查询')
})

getUsers.addImpl('string','string',(name,gender)=>{
    console.log("按照用户名和性别查询")
})

getUsers(); //得到所有用户
getUsers(1); // 得到第一页的用户,默认10个
getUsers(1,20); // 得到第一页的20个用户
getUsers('张'); //查找姓名包含张的用户
getUsers('张','男'); //查找姓名为张且性别为男的用户

结果演示

image.png