【TypeScript】TS进阶-函数重载(七)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
🐱个人主页不叫猫先生
🙋♂️作者简介前端领域新星创作者、阿里云专家博主专注于前端各领域技术共同学习共同进步一起加油呀
💫系列专栏vue3从入门到精通、TypeScript从入门到实践
📢资料领取前端进阶资料以及文中源码可以找我免费领取
🔥社群招募博主建立了一个前端交流群汇集了各路大神期待你的加入(文末有我wx或者私我)
目录
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)