TypeScript 函数的重载

函数的重载


什么是函数重载呢?允许函数接收不同数量或类型的参数时,做出不同的处理。比如说这个例子:


function double(x: number | string): number | string {
if (typeof x === 'number') {
return x * 2;
} else {
return x + ', ' + x;
}
}

本来这个函数,期望输入是 number,输出就是 number。或者输入是 string,输出就是 string。但是我们使用这种联合类型来书写的话,就会存在一个问题。


image-20211011230002191.png


那如何解决这个问题呢?我们可以使用函数的重载


function double(x: number): number; // 输入是 number 类型,输出也是 number 类型
function double(x: string): string;
function double(x: number | string): number | string {
if (typeof x === 'number') {
return x * 2;
} else {
return x + ', ' + x;
}
}

let d = double(1);

image-20211011230140623.png
需要注意的是,函数重载是从上往下匹配,如果有多个函数定义,有包含关系的话,需要把精确的,写在最前面。


习题-根据函数重载知识,完善下面代码块


function paramType (param: ______): string;
function paramType (param: string): string;
function paramType (param: string | number): string {
return typeof param;
};

paramType('panda');
paramType(10);

答案:number


解析:


重载允许一个函数接收不同数量或类型的参数,然后做不同处理。


// 函数声明
function paramType (param: ______): string;
function paramType (param: string): string;
// 函数实现
function paramType (param: string | number): string {
return typeof param;
};

在函数实现中参数的类型为 string | number,故答案为 number;


资料-高阶函数


在维基百科中对于高阶函数的定义是这样的:



在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数:



  • 接受一个或多个函数作为输入
  • 输出一个函数


在 JavaScript 的世界中,大家应该都有听说过「函数是一等公民」( first-class citizens )的说法。这里实际上是指在 JavaScript 中,函数被视为 Object 类型,我们可以将函数( function )作为参数传递给其他函数,并且也可以将函数作为其他函数的返回值传递。


因为函数是对象,所以 JavaScript 天然就支持高阶函数的写法。


或许你对高阶函数感到陌生,但实际上在日常的代码编写中,我们一定都用到过高阶函数。


接受一个或多个函数作为输入


我们在日常的学习和开发中,一定遇到过使用回调函数( callback )的场景。回调函数是在完成所有其他操作后,在操作结束时执行的函数。我们通常将回调函数作为最后一个参数,用匿名函数的形式传入。在拥有异步操作的场景中,支持回调函数的传入是至关重要的。


例如我们发送一个 Ajax 请求,我们通常需要在服务器响应完成后进行一些操作,同时在 Web 端,一些需要等待用户响应的行为,如点击、键盘输入等场景也需要用到回调函数。我们看下面的例子


let $submitButton = document.querySelector('#submit-button');

$submitButton.addEventListener('click', function() {
alert('您点击了提交按钮!');
});

这里我们通过将匿名函数作为参数的形式将它传递了 addEventListener 函数。我们也可以改造一下:


let $submitButton = document.querySelector('#submit-button');

let showAlert = function() {
alert('您点击了提交按钮!');
}

$submitButton.addEventListener('click', showAlert);

请注意,这里我们给 addEventListener 传递参数的时候,使用的是 showAlert 而不是 showAlert()。在没有括号的时候,我们传递的是函数本身,而有括号的话,我们传递的是函数的执行结果。


这里将具名函数( named function )作为参数传递给其他函数的能力也为我们使用纯函数(pure functions )提供了很大的想象空间,我们可以定义一个小型的 纯函数库 ,其中的每个纯函数都可以作为参数被复用至多处。


将函数作为结果返回


我们来假想一种场景:假如你拥有一个个人网站,在里面写了很多篇文章。在你的文章中经常介绍你的个人网站,网址是 myblog.com,后来你的站点域名变成了 my-blog.com。这时候你需要将文章中的 myblog.com 替换为 my-blog.com。你或许会这样做:


let replaceSiteUrl = function(text) {
return text.replace(/myblog\.com/ig, 'my-blog.com');
}

在域名变更后,你又想更改网站名称,你可能会这么做:


let replaceSiteName = function(text) {
return text.replace(/MySite/ig, 'MyBlog');
}

上述做法是行之有效的,但是你或许会烦于每次信息变更都要写一个新的函数来适配,而且上述两段代码看起来相似度极高。这时候我们可以考虑使用 高阶函数 来复用这段代码:


let replaceText = function(reg, newText, source){
return function(source) {
return source.replace(reg, newText);
}
}

let replaceSiteUrl = replaceText(/myblog\.com/ig, 'my-blog.com');

console.log(replaceSiteUrl('My site url is https://myblog.com')); // My site url is https://my-blog.com

在上述代码中,我们用到了 JavaScript 函数并不关心他们收到多少个参数的特性,如果没有传递会自动忽略并且认为是 undefined。


总结


高阶函数看起来并没有那么神秘,它是我们日常很自然而然就用到的场景。高阶函数可以帮助我们将一些通用的场景抽象出来,达到多处复用的结果。这也是一种良好的编程习惯。


链接:https://juejin.cn/post/7029481950691737630

0 个评论

要回复文章请先登录注册