TypeScript 的函数相关
●函数, 一个再熟悉不过的话题了, 之前几章里面我们也多次提到过, 而且提到过各种各样的 TS 内和函数相关的内容 ●今天, 咱们来详细说一下函数内的各种详细内容的使用
函数的可选参数 ●在 TS 中, 是可以给函数的参数添加类型限制的, 先来看一个例子
function fn(a: number, b: number): void {}
○这就是一个很简单的函数 ○我们使用的时候, 只要给两个 number 类型的数据作为参数即可 ●现在呢, 我有一个想法, 就是我使用这个函数的时候, 第二个参数可不可以不填 ○小伙伴: "这还不简单吗, 给形参来一个默认值"
function fn(a: number, b: number = 0): void {}
○完成任务了, 好简单 ●但是我要说的不是这个, 而是当你的逻辑内需要判断用户是不是没有传递参数的时候
●咱们来看下面两个需求 ○需求1: 如果确实传递了两个参数, 那么我按照两个参数去计算结果, 如果第二个没有传递, 我给个默认值, 还是按照两餐参数去计算结果
// 比如, 我们的随机数函数
function fn(a: number = 10, b: number = 0): number {
return Math.floor(Math.random() * (Math.abs(a - b +1))) + Math.min()
}
●你传了参数, 我就用你传的, 你没有传递的时候, 那么我就用我自己设定的默认值就好了 ○需求2: 如果传递了两个参数, 我执行两个参数的逻辑, 如果第二个参数没有传递, 那么我就按照一个参数来执行逻辑
// 比如, 我们设置 cookie 的时候的一个简单的操作
function fn(a: string, b: string, c: number): void {
let time
if (c) {
time = new Date()
time.setTime(time.getTime() - 1000 * 60 * 60 * 8 + 1000 * c)
}
document.cookie = `${ a }=${ b };expires=${ c }`
}
●你传递了参数 c, 那么我就用, 你没有传递 c, 那么我就不用就好了 ●以上两段逻辑明显不一样 ○其实, 说了这么多, 我就是想告诉你们一个事情 ○那就是函数的参数可以设置选填
function fn(a: number, b?: number): void {}
○只要在书写形参的时候, 在形参后面加上一个 问号(?) 就可以了 ○就像我们在对象接口内书写选填成员一样 ○这样, 这个参数就可以不传递了, 也不会报错 ●注意 1.必选参数不可以放在选填参数的后面
2.选填参数不允许设置默认值了
函数内的虚拟 this
●这里我们说的可不是函数内的 this 指向谁, 而是如何对函数内的 this 进行类型限制 ●小伙伴: " 什么, this 还需要限制吗 ? " ●当然了, 既然是类型限制, 那么我们一个也不要放过了 ●先来看一个函数
function fn() {
console.log(this.innerHTML)
}
○这是一个非常简单的函数 ○如果我们把它当做某一个元素的事件处理函数, 是完全没有问题的 ○但是这里的 this 并没有做出任何限制, 那么在使用的时候会不会出现问题呢 ? ○TS 一定会考虑这个问题, 所以会给你提示一个错误
●所以在 TS 的配置文件内, 有一个配置
{
"noImplicitThis": true, // false
}
○默认值是 true, 表示在你的项目内不允许出现没有类型限制的 this ○选填是 false, 表示不管你的 this 是什么, ts 都不管了 ○所以这是一个解决方案 ●但是很显然, 这并不友好, 我们最好还是给 this 加上一个限制 ○在这里, 我们就可以在书写函数的时候, 在参数的第一个位置, 加上一个 this 的限制
function fn(this: HTMLDivElement) {
console.log(this.innerHTML)
}
○这里的 this 并不是该函数的第一个参数, 而是一个虚拟参数, 只是限定了该函数内的 this 数据类型 ○既然在这里已经做出了限制, 那么函数内在使用的时候就不会提示错了 ○但是也说了, 这个函数在调用的时候, 必须要让函数内 this 为 HTMLDivElement 类型
function fn(this: HTMLDivElement) {
console.log(this.innerHTML)
}
// box 是获取到得以一个 div 元素
box.onclick = fn
这样就可以, 完全没有问题的
function fn(this: HTMLDivElement) {
console.log(this.innerHTML)
}
fn()
○这样就会提示错误了
○因为要求函数内的 this 必须是 HTMLDivElement 类型 ○但是如果你直接调用 fn 函数的话, 内部的 this 并不是 HTMLDivElement 类型 ○就会提示错误了 ●注意: 我们一定要分清, 这个 this 限定并不是函数的第一个参数
函数的重载 ●啥也不说了, 先看一个例子吧 ○有一个简单的函数, 实现字符串反转操作
function fn(x: string): string {
return x.split('').reverse().join('')
}
○在来一个函数, 实现一个数字放大 100 倍的操作
function fn(x: number): number {
return x * 100
}
○因为某些原因, 我必须要要讲两个函数合并为一个函数
function fn(x: string | number): string | number {
// 需要在函数内进行条件判断
if (typeof x === 'number') {
return x * 100
} else {
return x.split('').reverse().join('')
}
}
●上面这个函数, 看起来没有任何问题, 我们也可以正常使用 ○但是, 我发现使用完毕以后出现了问题
●惊不惊喜, 意不意外, 这是为什么 ?
根据这个函数, 我们来看 参数限定 : 可以是 string 也可以是 number 返回值限定 : 可以是 string 也可以是 number 看似没有问题, 但是呢 ... 它并没有限制什么参数对应什么返回值 比如, 我们如果参数是 string, 那么返回值可以是 string 或者 number 比如, 我们如果参数是 number, 那么返回值也可以是 string 或者 number 并不是我们一开始想要的 参数是 string 返回值也是 string 参数是 number 返回值也是 number 那么当我们调用的时候, 不管你传递的是什么参数 ts 都会认为, 返回值是 string 或者 number 类型 当你用返回值调用 toFixed 的时候 ts 就会认为, 你有可能是一个 string 类型, 那么 string 类型是没有 toFixed 这个方法的, 所以就会提示错误 也就是说, 你这样写完 如果你再也不用返回值了, 那么没啥事 但是如果你要用返回值去调用一些方法, 那么只能调用两种数据类型共有的方法
●那我该怎么办 ? ●这个时候, 就可以用到 函数的重载 了 ●其实就是在定义函数之前, 把这个函数我需要的几种情况列举出来
// 情况1:
function fn(x: string): string
// 情况2:
function fn(x: number): number
function fn(x: string | number): string | number {
if (typeof x === 'number') {
return x * 100
} else {
return x.split('').reverse().join('')
}
}
○函数还是这个函数 ○但是在这个函数之前, 我们列举了两种情况 ■参数是 string, 返回值也是 string ■参数是 number, 返回值也是 number ●今后在调用的时候, 就只会出现这两种情况了
●这样就不会报错了
转载自:https://juejin.cn/post/7226166316670451768