js模拟重载

概述

众所周知,js里面是没有函数重载这一说的,主要有如下的几个原因:

1. 动态类型语言特性

JavaScript 是一种动态类型语言,函数的参数在定义时不需要指定类型。这与支持重载的静态类型语言(如 Java、C++)不同,那些语言可以根据参数类型和数量来区分不同的函数实现。

2. 函数参数处理机制

JavaScript 函数在被调用时:

  • 不检查参数数量(可以传递比声明多或少的所有参数)
  • 所有参数都被存储在 arguments 对象中(ES6 之前)
  • 多余的参数会被忽略,缺少的参数会被赋值为 undefined

3. 函数签名唯一性

在 JavaScript 中,函数名是唯一的标识符,后定义的函数会覆盖同名的先前定义,无法像传统重载那样保留多个版本。

模拟实现

核心思路:闭包,通过借助闭包函数的缓存特性,返回加工后的函数,然后通过map缓存对于参数类型到函数具体实现,即可实现重载

实现

js 复制代码
// 构造重载函数
function createOverload() {
  // 定义一个map结构,缓存不同参数类型对应的函数实现
  const fnMap = new Map();
  function overload(...args) {
    // 获取调用参数的类型列表
    const key = args.map((arg) => typeof arg).join(",");
    // 从map中获取对应的函数实现
    const fn = fnMap.get(key);
    if (!fn) {
      throw new Error(`No function registered for arguments: ${key}`);
    }
    // 调用对应的函数实现
    return fn.apply(this, args);
  }

  //   追加重载实现函数
  overload.addImpl = function (...args) {
    console.log("Adding implementation for:", args);
    // 最后一个参数必须是函数
    const fn = args.pop();
    if (typeof fn !== "function") {
      throw new Error("Last argument must be a function");
    }
    console.log("fn-map", fnMap);
    const key = args.join(",");
    // 将参数类型作为key存储函数实现
    fnMap.set(key, fn);
  };

  return overload;
}

const getUsers = createOverload();

// 无参情况
getUsers.addImpl(() => {
  console.log("No arguments provided");
});

const searchPage = (page, size = 10) => {
  console.log(`Searching page ${page} with size ${size}`);
};

// 参数:number
getUsers.addImpl("number", searchPage);

// 参数:number, number
getUsers.addImpl("number", "number", searchPage);

// 参数:string
getUsers.addImpl("string", (name) => {
  console.log("String argument provided", name);
});

// 参数:string:number
getUsers.addImpl("string", "number", (name, age) => {
  console.log(`Searching for user ${name} with age ${age}`);
});

// 使用

getUsers();

getUsers(1); // Searching page 1 with size 10

getUsers(1, 20); // Searching page 1 with size 20

getUsers("Alice"); // String argument provided

getUsers("Alice", 30); // Searching for user Alice with age 30

结果

总结

虽然js中并不存在函数重载,但是我们依然能够通过间接形式实现对于的功能。

相关推荐
程序猿小蒜几秒前
基于springboot的的学生干部管理系统开发与设计
java·前端·spring boot·后端·spring
银空飞羽几秒前
让Trae CN SOLO自主发挥,看看能做出一个什么样的项目
前端·人工智能·trae
Eshine、1 小时前
解决前端项目中,浏览器无法正常加载带.gz名称的文件
前端·vue3·.gz·.gz名称的js文件无法被加载
q***38511 小时前
TypeScript 与后端开发Node.js
javascript·typescript·node.js
用户47949283569151 小时前
别再当 AI 的"人肉定位器"了:一个工具让 React 组件秒定位
前端·aigc·ai编程
Nan_Shu_6142 小时前
学习:Sass
javascript·学习·es6
WYiQIU2 小时前
面了一次字节前端岗,我才知道何为“造火箭”的极致!
前端·javascript·vue.js·react.js·面试
qq_316837752 小时前
uniapp 观察列表每个元素的曝光时间
前端·javascript·uni-app
小夏同学呀2 小时前
在 Vue 2 中实现 “点击下载条码 → 打开新窗口预览 → 自动唤起浏览器打印” 的功能
前端·javascript·vue.js
芳草萋萋鹦鹉洲哦2 小时前
【vue】导航栏变动后刷新router的几种方法
前端·javascript·vue.js