这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战
在TypeScript中 声明和调用函数的不同方式有:
- 签名重载
- 多态函数
- 多态类型
函数声明和调用
在JavaScript中函数是一等公民,也就是我们像使用对象那样使用函数:可以赋值给变量、可以作为参数传给其他函数、也可以作为函数的返回值、可以赋值给对象和原型、可以赋予属性、可以读取属性等等
在TypeScript中,通常声明函数时,如果有形参,都会显示注解参数的类型。如下示例;TypeScript能推导出函数体中的类型,但是大多数时候无法推导出参数的类型。返回类型能推导出来,不过也可以显示注解
function sum(a: number, b: number): number {
return a + b
}
声明函数的五种方式:
-
具名函数
function sayHi(name: string) { return name + "hi~" } -
函数表达式
let sayHi = function(name: string){ return name + "hi~" } -
箭头函数
let sayHi = (name: string) => { name + "hi~" } -
箭头函数表达式简写形式
let sayHi = (name: string) => name + "hi~" -
函数构造方法
let sayHi = new Function('name', 'return name + "hi~"')
通常情况下形参的类型需要注解,返回参数的类型不要求必须注解
可选参数和默认参数
与对象和元组类型一样,可以使用?把参数标记为可选;声明函数的参数的时候,可选参数必须要在必传参数的后面;如下:
function handleLog(message: string, nickname?: string) {
const time = new Date().toLocaleTimeString()
console.log(time, message, nickname ?? '')
}
handleLog('今天天气不错~~') // 上午7:09:59 今天天气不错~~
handleLog('今天天气不错~~', 'Forest') // 上午7:09:59 今天天气不错~~ Forest
与在JavaScript中一眼给,可以为可选参数提供默认值;这样做在语义上与把参数标记为可选的一样,即在调用无需传入参数的值
默认值的参数不要求放在参数列表的结尾,而可选参数必须放在末尾
将上面示例的可选参数改为默认参数,也就是当这个参数传值了就用传的值,如果没有,则使用默认值。这个默认参数可以不声明类型,因为TypeScript可以根据值推导出对应的类型,从而保证代码简洁、易于理解
function handleLog(message: string, nickname = 'Forest') {
const time = new Date().toLocaleTimeString()
console.log(time, message, nickname)
}
handleLog('今天天气不错~~') // 上午7:13:27 今天天气不错~~ Forest
handleLog('今天天气不错~~', 'clin') // 上午7:13:27 今天天气不错~~ clin
当然,如果愿意,也可以显示注解默认参数的类型,就像默认值的参数一样:
type Content = {
id?: number
nickname?: string
}
function handleLog(message: string, content: Content = {}) {
const time = new Date().toLocaleTimeString()
console.log(time, message, content?.nickname)
}
剩余参数
如果一个函数接受一组参数时,可以使用数组或者元组传入:
function handleSum(numbers: number[]) {
return numbers.reduce((total, n) => total + n, 0)
}
console.log(handleSum([1, 1, 2, 3, 5, 8, 13, 21, 34])) // 88
不过,有时我们需要的是可变参数函数,即参数的数量不定;此时就可以用到arguments了,arguments是个类似数组的对象,在调用内置的.reduce()之前要把它转为数组
function handleSum() {
return Array.from(arguments).reduce((total, n) => total + n, 0)
}
call、bind、apply
调用函数,除了使用圆括号()外,JavaScript至少还支持两种其他方式
function handleAdd(a: number, b: number) {
return a + b
}
handleAdd(1, 2) // 3
handleAdd.apply(null, [1, 2]) // 3
handleAdd.call(null, 1, 2) // 3
handleAdd.bind(null, 1, 2)() // 3
apply()为函数内部的this绑定一个值,然后展开第二个参数,作为参数传给要调用的函数
call()的用法类似,不过是按顺序应用参数的,而不是展开
bind()差不多,也为函数的this和参数绑定值;不过bind()并不是调用函数,而是返回一个新的函数,所以使用bind()还得自己手动调用