网易面试官:请你实现一下JS重载?可不是TS重载哦!

开发 前端
我第一次看到重载​这个词还是在以前学习Java​的时候,我一直觉得JavaScript​是没有重载的,直到TypeScript​的出现,所以我一直觉得JavaScript​没有重载,TypeScript才有,但是现在看来我是错的。

什么是重载

我第一次看到重载这个词还是在以前学习Java的时候,我一直觉得JavaScript是没有重载的,直到TypeScript的出现,所以我一直觉得JavaScript没有重载,TypeScript才有,但是现在看来我是错的。

我理解的重载是:同样的函数,不同样的参数个数,执行不同的代码,比如:

/*
* 重载
*/
function fn(name) {
  console.log(`我是${name}`)
}

function fn(name, age) {
  console.log(`我是${name},今年${age}岁`)
}

function fn(name, age, sport) {
  console.log(`我是${name},今年${age}岁,喜欢运动是${sport}`)
}

/*
* 理想结果
*/
fn('林三心') // 我是林三心
fn('林三心', 18) // 我是林三心,今年18岁
fn('林三心', 18, '打篮球') // 我是林三心,今年18岁,喜欢运动是打篮球

但是直接在JavaScript中这么写,肯定是不行的,咱们来看看上面代码的实际执行结果,可以看到,最后一个fn的定义,把前面两个都给覆盖了,所以没有实现重载的效果。

我是林三心,今年undefined岁,喜欢运动是undefined
我是林三心,今年18岁,喜欢运动是undefined
我是林三心,今年18岁,喜欢运动是打篮球

我的做法

其实,想要实现理想的重载效果,我还是有办法的,我可以只写一个fn函数,并在这个函数中判断arguments类数组的长度,执行不同的代码,就可以完成重载的效果。

function fn() {
  switch (arguments.length) {
    case 1:
      var [name] = arguments
      console.log(`我是${name}`)
      break;
    case 2:
      var [name, age] = arguments
      console.log(`我是${name},今年${age}岁`)
      break;
    case 3:
      var [name, age, sport] = arguments
      console.log(`我是${name},今年${age}岁,喜欢运动是${sport}`)
      break;
  }
}

/*
* 实现效果
*/
fn('林三心') // 我是林三心
fn('林三心', 18) // 我是林三心,今年18岁
fn('林三心', 18, '打篮球') // 我是林三心,今年18岁,喜欢运动是打篮球

但是那位同学说,网易的面试官好像觉得这么实现可以是可以,但是还有没有更好的实现方法,我就懵逼了。

高端做法

经过了我的一通网上查找资料,发现了一种比较高端的做法,可以利用闭包来实现重载的效果。这个方法在JQuery之父John Resig写的《secrets of the JavaScript ninja》中,这种方法充分的利用了闭包的特性!

function addMethod(object, name, fn) {
  var old = object[name]; //把前一次添加的方法存在一个临时变量old里面
  object[name] = function () { // 重写了object[name]的方法
    // 如果调用object[name]方法时,传入的参数个数跟预期的一致,则直接调用
    if (fn.length === arguments.length) {
      return fn.apply(this, arguments);
      // 否则,判断old是否是函数,如果是,就调用old
    } else if (typeof old === "function") {
      return old.apply(this, arguments);
    }
  }
}

addMethod(window, 'fn', (name) => console.log(`我是${name}`))
addMethod(window, 'fn', (name, age) => console.log(`我是${name},今年${age}岁`))
addMethod(window, 'fn', (name, age, sport) => console.log(`我是${name},今年${age}岁,喜欢运动是${sport}`))

/*
* 实现效果
*/

window.fn('林三心') // 我是林三心
window.fn('林三心', 18) // 我是林三心,今年18岁
window.fn('林三心', 18, '打篮球') // 我是林三心,今年18岁,喜欢运动是打篮球

参考资料

  • 浅谈JavaScript函数重载
责任编辑:武晓燕 来源: 前端之神
相关推荐

2023-09-12 14:56:13

MyBatis缓存机制

2024-02-27 15:23:48

RedLock算法Redis

2024-01-29 10:08:11

零拷贝Zero-copyCPU 拷贝

2021-07-28 10:08:19

类加载代码块面试

2011-03-14 10:47:30

HashMap

2021-11-08 15:59:01

MyBatis关联开发

2021-08-28 09:06:11

Dubbo架构服务

2022-06-07 12:03:33

Java内存模型

2023-02-08 08:32:41

轮询锁

2023-02-18 13:34:14

Nacos健康检查机制

2022-06-06 15:33:20

线程Java释放锁

2021-06-02 11:25:18

线程池Java代码

2020-07-30 07:58:36

加密算法

2024-02-21 16:42:00

2023-03-08 07:46:53

面试官优化结构体

2023-12-29 13:45:00

2023-11-29 08:00:53

JavaTreeMap底层

2022-02-28 08:17:24

重载函数JS前端

2024-07-15 09:08:51

2023-01-30 15:39:40

GETHTTP
点赞
收藏

51CTO技术栈公众号