TypeScript 高级语法——函数

前文没有提到普通的TS函数写法,但是在示例里却有使用,在这一章详细说明一下TS函数。
上述示例是三种TS函数声明的一种,这种声明方法被称为具名函数声明,其特点是会获得“顶级提升”,在同一上下文中,无论声明顺序先后,都可以自由的使用该函数。
函数声明由“function”关键字开头,funcName为函数名,函数名后的括号内是函数的参数组成部分。
参数的写法是:“参数名 : 参数类型”,函数支持多个参数,参数之间以逗号间隔,参数的类型可以是基础类型(string,number等),也可以是interface或者type或者直接临时类型标注(见上例temFunc函数)。restFunc函数展示的是一种特殊的函数参数声明方式:“剩余参数”,在函数的参数名前加“...”标记该参数被声明为剩余参数,剩余参数的类型一定是数组(因为除了参数a以外被传入的所有参数都会作为rest的内容存在)。在TS中因为开启了严格模式所以禁止使用arguments关键字,所以想使用类似arguments的功能只能使用ES标准中引入的剩余参数语法,其对比arguments的优点是可以认为的规定从哪个参数位置起算作剩余参数的组成部分,在restFunc示例中同时存在参数“a : string”和“rest : any[ ]”,也就是说从第二位起算作rest参数的组成部分。rest在此例中被标记为any数组只是表示任何类型的参数都可以被传入剩余参数,这点要视实际使用情况决定,这里如果可预判的rest的组成一定都是数字那么rest的类型就可以是number[ ]。
在函数参数的声明之后紧跟的部分是函数的返回值部分,返回值声明的写法是冒号加返回值类型,绝大多数情况下返回值是可省略的,因为TS会根据函数体内的逻辑判断出返回值的类型(如temFunc,restFunc)。
这个示例演示的是具有默认值的函数参数(paramOne)和可选参数(paramTwo)。具有默认值的参数写法是在参数名后使用“=”后加默认值,在实际使用参数时如果未传入该参数则默认值生效。具有默认值的参数可以省略参数类型声明,因为默认值的类型几乎就可以表示参数类型;可选参数声明方式是“?:”,与普通参数声明相比冒号前面多了问号,在实际使用时可选参数未被传入则参数值为“undefined”,所以paramTwo的类型实际为“string | undefined”联合类型。
上例表示的为匿名函数的声明方式,几乎具名函数所有的功能都可以用在匿名函数上,与具名函数声明不同的是省略掉了声明中的函数名称部分,将函数声明的结果赋给一个字段。这种声明方式不会获得顶级提升,因为我们现在用一个字段引用一个匿名函数,遵循的是字段声明的规则(先定义,再使用)。
上例为箭头函数的声明方式,箭头函数去掉了function关键字,使用表达式中间的“=>”表示自己的语法。箭头函数与匿名函数几乎相同,唯一的区别在于函数内“this”的判定上,以function关键字声明的函数,函数体内部的this指向其调用者(a.b( )中函数b内的this为a),箭头函数函数体内部的this指向函数声明所处上下文的this,在vue项目中我们经常使用箭头函数规避以声明that、self、_this等约定字段对this的临时存储。
当箭头函数的函数体极其简单,只有返回表达式时,可以简写为示例中simple的形式。
我们在这个例子中演示了如何标记以function关键字声明的函数的this(在第一个参数的位置将参数名起名为this,并标记this的类型,示例中为number),这样我们就能在函数体内部为this的使用加入TS类型系统为我们提供的能力,要注意的是在使用这个函数时并不需要将this传入第一个参数的位置,第一个参数仅仅是一个对函数内this的一个TS描述,也就是说其实param才是实际使用时传入的第一个参数。箭头函是不需要描述其内部的this的,因为TS会根据箭头函数的声明位置在上下文中确定其this 的类型。
上面这个例子演示了如何定义函数类型的参数,在不需要描述this的情况下我都喜欢使用箭头函数的形式描述函数签名,大多数情况在不需要复用的情况下推荐使用上例中func函数的声明形式。