【TypeScript】TS进阶-函数重载(七)

【TypeScript】TS进阶-函数重载(七)

🐱个人主页:不叫猫先生
🙋‍♂️作者简介:前端领域新星创作者、阿里云专家博主,专注于前端各领域技术,共同学习共同进步,一起加油呀!
💫系列专栏:vue3从入门到精通、TypeScript从入门到实践
📢资料领取:前端进阶资料以及文中源码可以找我免费领取
🔥社群招募:博主建立了一个前端交流群,汇集了各路大神,期待你的加入!(文末有我wx,或者私我)

目录

  • 专栏介绍
  • 函数默认参数/可选参数
  • 函数重载
    • 1、函数签名
    • 2、构造器重载
    • 3、联合类型函数重载
  • 拓展JS中函数重载
    • 1、利用arguments参数
    • 2、利用闭包和arguments

专栏介绍

TypeScript从入门到实践专栏是博主在学习和工作过程中的总结,内容会不断进行精进,实用性非常强,欢迎订阅哦,学会TS不迷路。

TS系列 标题
基础篇 TS入门(一)
基础篇 TS类型声明(二)
基础篇 TS接口类型(三)
基础篇 TS交叉类型&联合类型(四)
基础篇 TS类型断言(五)
基础篇 TS类型守卫(六)
进阶篇 TS函数重载(七)
进阶篇 TS泛型(八)
进阶篇 TS装饰器(九)

函数默认参数/可选参数

对于同一个函数我们在不同场景下传参,参数有时候全部需要,有时候部分需要,定义多个同名函数就会报错,那么该怎么实现这个操作呢?我们可以为函数设置默认参数和可选参数。
给每个参数添加类型之后,可以不用给函数本身添加返回值类型,因为TS能根据返回语句自动推断出返回值类型

function start(name:string,age:number,phone?:number,sex?:string):string{
   if(phone&&sex){
        return `name:${name},age:${age},phone:${phone},sex:${sex}`
   }else{ 
        return `name:${name},age:${age}`
   }
}
start('zhangsan','14')//name:zhangsan,age:14
start('zhangsan','14',15678777777,'男')//name:zhangsan,age:14,phone:15678777777,sex:男

另外我们看它编译后的样子,其中返回值使用了concat来连接字符串,也让我们学习到模版字符串的实现原理。

function start(name, age, phone, sex) {
    if (phone && sex) {
        return "name:".concat(name, ",age:").concat(age, ",phone:").concat(phone, ",sex:").concat(sex);
    }
    else {
        return "name:".concat(name, ",age:").concat(age);
    }
}
start('zhangsan', 14); //name:zhangsan,age:14
start('zhangsan', 14, 15678777777, '男'); //name:zhangsan,age:14,phone:15678777777,sex:男

但是我们要是有很多场景,参数类型也都不一致,我们这样写很难维护,并且定义的规范很难适用于实际多个场景,那么我们可以使用函数重载来处理。

函数重载

什么事函数重载呢?当我们多次调用函数时传递不同参数数量或者类型,函数会做出不同处理。

1、函数签名

这里介绍个名次「函数签名」,顾名思义,函数签名主要定义了参数及参数类型,返回值及返回值类型。函数签名不同,函数会做出不同的处理,这是我对函数重载的理解。

2、构造器重载

举个例子,声明一个类Course,里面写一个start的方法,我们调用 start时传入不同参数类型已经参数个数,start方法会做出不同处理,那么怎么实现呢?具体如下:

type Combinable = number | string;
class Course {
   //定义重载签名
   begin(name: number, score: number): string;
   begin(name: string, score: string): string;
   begin(name: string, score: number): string;
   begin(name: number, score: string): string;
   //定义实现签名
   begin(name: Combinable, score: Combinable) {
       if (typeof name === 'string' || typeof score === 'string') {
           return 'student:' + name + ':' + score; 
       }
   }
}
const course = new Course();
course.begin(111, 5);//没有输出
course.begin('zhangsan', 5);//student:zhangsan:5
course.begin(5, 'zhangsan');//student:5:zhangsan

以上代码中定义了4个重载前面和1个实现签名。

3、联合类型函数重载

声明一个函数arithmetic,参数类型为联合类型,返回值也是联合类型,但是如下代码却报错了。

function arithmetic(x: number | string): number | string {
    if (typeof x === 'number') {
        return x;
    } else {
        return x+'是字符串';
    }
}
arithmetic(1).length;

在这里插入图片描述

原因是没有明确函数string类型没有toFixed属性`,那么怎么用函数重载解决这个报错问题呢?
我们可以可以根据传参的类型和函数返回值声明多个同名的函数,只是类型和返回值不同而已。

function arithmetic(x: number): number;
function arithmetic(x: string): string; 
function arithmetic(x: number | string): number | string {
    if (typeof x === 'number') {
        return x;
    } else {
        return x+'是字符串';
    }
}
arithmetic(1).toFixed(1);

这样就不会报错啦,因为已经识别到arithmetic(1)的返回值是number类型。

拓展JS中函数重载

JS中函数重载怎么实现呢?

1、利用arguments参数

var arr = [1,2,3,4,5];
//注意:这里不能写成箭头函数,否则this指向的是window对象
Array.prototype.search = function() {
   var len = arguments.length;
   switch(len){
   case 0:
	 return this;
   case 1:
	 return `${arguments[0]}`;
   case 2:
	 return `${arguments[0]},${arguments[1]}`;
  }
}
console.log(arr.search()) //[1,2,3,4,5]
console.log(arr.search(1)) //1
console.log(arr.search(1,2)) //1,2

2、利用闭包和arguments

 function addMethod (obj, name, fn) {
        var old = obj[name];
        obj[name] = function () {
            if (fn.length === arguments.length) {
                return fn.apply(this, arguments)
            } else if (typeof old === 'function') {
                return old.apply(this, arguments)
            }
        }
    }
    var person = {name: 'zhangsan'}
    addMethod(person, 'getName', function () {
        console.log(this.name + '---->' + 'getName1')
    })
    addMethod(person, 'getName', function (str) {
        console.log(this.name + '---->' + str)
    })
    addMethod(person, 'getName', function (a, b) {
        console.log(this.name + '---->' + (a + b))
    })
    person.getName()  
    person.getName('zhangsan')
    person.getName(10, 20)
                       

点击阅读全文

上一篇 2023年 6月 16日 am4:33
下一篇 2023年 6月 16日 am10:14