TypeScript学习(六):函数的定义及特性

前面我们说完了对象和数组的定义,接下来就是一个重头戏---函数。函数可谓是在程序猿界无处不在,不管你学什么语言,都会接触到函数,我看有的文章将函数定义为一等公民,这就可以看得出函数对于我们来说地位是多么的高,是多么的重要,废话不多说,我们进入正题。

老样子,我们先说一下在JavaScript中,对于函数的定义和使用。什么是函数?函数就是被开发者用来执行某一项或多项功能任务的代码块。在JS中定义函数的方式通常有以下几种:

// 方式1
var sum = function (a, b) {
    return a + b
}

// 方式2
function sum(a, b) {
    return a + b
}

// 方式3
var sum = (a, b) => a + b

// 方式4
var sum = new Function("a", "b", "return a + b")

其中,方式1和方式2比较常见,方式3是ES6中的箭头函数表达式,这种箭头函数表达式很好的解决了开发中的this指向问题,后续会出一篇博客单独讲解这个,在这里就不赘述了,方式4是以构造函数的方式,在实际开发中用的很少,了解即可。

下面说一下在typescript中函数的定义方式,结合前面关于对象及数组的定义方式,我们可以采取结合数据类型定义的方式来定义函数(类似于上述JavaScript定义方式2),如下:

// 声明函数中的输入和输出的数据类型
function sum(x: number, y: number): number {
    return x + y;
}

在这里我们定义了函数sum的输入和输出的数据类型,均为number类型,所以在调用函数的时候必须按照定义的格式严格执行,以下调用的方式均为错误方式,如下:

// 情形一:参数比定义的多
function sum(x: number, y: number): number {
    return x + y;
}
sum(1, 2, 3);  // 编译报错:Expected 2 arguments, but got 3.

// 情形二:参数比定义的少
function sum(x: number, y: number): number {
    return x + y;
}
sum(1);  // 编译报错:Expected 2 arguments, but got 1.

// 情形3:参数类型不是定义的数据类型及其子类型
function sum(x: number, y: number): number {
    return x + y;
}
sum(1, '2');   // 编译报错:Argument of type '"2"' is not assignable to parameter of type 'number'.

当然,我们可以写类似于上述JavaScript中方式一的定义方式来定义函数表达式,如下:

let sum = function (x: number, y: number): number {
    return x + y;
}

上面这样的写法没有错,但是不够严谨,因为我们可以看到上面的写法仅对表达式右边的函数的类型进行了定义,而没有对等号左侧的进行定义,这样就类似于我们前面提到的数据类型推论,根据右侧的定义来推断左侧的类型,所以,我们可以在定义右侧类型的同时,也给左侧添加类型,如下:

let sum: (x: number, y: number) => number = function (x: number, y: number): number {
    return x + y;
}

这种定义方式中,可以看到一个熟悉的符号 '=>',瞬间想起了箭头函数,有木有!!!!!!可惜,这里的 '=>'跟箭头函数的那个完全没关系,在 typescript 的类型定义中,'=>'用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。切记!!!!

我们一直在重复一句话,万物皆对象,是的,函数也可以用类似于对象接口的定义方式,如下:

// 创建一个Sum的接口,定义输入输出数据类型
interface Sum{
    (x: number, y: number): number;
}
// 定义一个函数sum,它的类型是Sum
let sum: Sum;
// 创建函数sum,它的类型要符合接口Sum的定义
sum = function(x: number, y: number) {
    return x + y;
}

typescript的定义就说到这,我们接下来看一下关于typescript中函数的一些特性:

(1)定义函数时,参数可选,而且可选参数必须在后面,如下:

function sum(x: number, y?: number) {   // 切记:可选参数必须放在后面,不然会报错
    if (y) {
        return x + y;
    } else {
        return x;
    }
}
let sum_1 = sum(1, 2);
let sum_2 = sum(1);

(2)定义函数时,设置默认参数,设置的顺序没有限制,如下:

function sum(x: number, y: number = 3) {
    return x + y
}
let sum_1 = sum(1, 2);
let sum_2 = sum(1);


function sum(x: number = 3, y: number) {
    return x + y
}
let sum_1 = sum(1, 2);
let sum_2 = sum(undefined, 1);  // 注意这里的参数传入方式,如果定义默认参数的位置不在后面,那么我们需要一个占位的数据变量来占据输入参数的位置,而且TS编译也会报错:Expected 2 arguments, but got 1.

(3)定义函数时,可以利用...rest来表示剩余参数,这里的rest表示的就是参数,如下:

function push(array, ...items) {
    items.forEach(function(item) {
        array.push(item);
    });
}

let a = [];
push(a, 1, 2, 3);

// 这样看上去比较懵哈,附上编译好的JS代码作对比

function push(array) {
    var items = [];
    for (var _i = 1; _i < arguments.length; _i++) {
        items[_i - 1] = arguments[_i];
    }
    items.forEach(function (item) {
        array.push(item);
    });
}
var a = [];
push(a, 1, 2, 3);

(4)重载,就是允许一个函数接受不同数量或类型的参数时,作出不同的处理,也就是允许多类型的参数,我们要利用联合类型的方法来定义函数,如下:

function getResult(x: number): number;
function getResult(x: string): string;
function getResult(x: number | string): number | string {   // 重载的特性:最后一个相同函数名的会覆盖之前函数
    if (typeof x === 'number') {
        return x + 2
    } else if (typeof x === 'string') {
        return x + 'kreme'
    }
}

 

 

到底啦!!!!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值