美文网首页我爱编程
TypeScript 旅途4:函数

TypeScript 旅途4:函数

作者: 工匠前沿 | 来源:发表于2018-01-29 12:38 被阅读0次

    在JavaScript中,函数是一等公民。在TypeScript中虽然已经支持类,命名空间和模块,但函数的使用频率仍然是非常高的,而且还添加了额外的功能,使用起来更方便了。

    函数定义

    先来看一下在TypeScript中函数的定义。

    function add(x: number, y: number): number {
        return x + y;
    }
    
    let myAdd = function(x: number, y: number) {
        return x + y
    };
    console.log(myAdd(2, 3));
    

    TypeScript能够根据返回语句自动推断出返回值类型,因此我们通常省略它。

    下面让我们写出函数的完整类型。

    let myAdd: (x: number, y: number) => number =
        function(x: number, y: number): number {
            return x + y;
        }
    console.log(myAdd(2, 3));
    
    • 函数类型包含两部分:参数类型返回值类型。 当写出完整函数类型的时候,这两部分都是需要的。
    • 我们以参数列表的形式写出参数类型,为每个参数指定一个名字和类型,这个名字只是为了可读性,可以与函数参数中的名字不同。
    • 第二部分是返回值类型。 对于返回值,我们在函数和返回值类型之前使用( =>)符号,使之清晰明了。 如之前提到的,返回值类型是函数类型的必要部分,如果函数没有返回任何值,你也必须指定返回值类型为 void 而不能留空。

    在一边指定了类型但是另一边没有类型的话,编译器会自动推断类型。如:

    let myAdd: (x: number, y: number) => number =
        function(x, y) {
            return x + y;
        }
    console.log(myAdd(2, 3));
    

    可选参数和默认参数

    函数支持可选参数和默认参数。

    let myAdd: (x: number, y?: number) => number =
        function(x, y) {
            if (y) {
                return x + y;
            } else {
                return x + 3;
            }
        }
    function add(x: number, y = 3): number {
        return x + y;
    }
    console.log(myAdd(2));
    console.log(add(2));
    
    • 参数名称后面跟着表示是可选参数,调用的时候可以不传这个参数。
    • 参数名称后面直接跟 = 值 表示这个参数有默认值,当调用函数时不传递这个参数或传了个 undefined ,函数会使用这个默认值。
    • 如果带默认值的参数后面还有不带默认值的非可选参数,那么调用函数的时候这个带默认值的参数位置必须传值或是使用 undefined ,意思是不能跳过这个带默认值的参数(如:function add( y = 3, x: number),则调用函数使用add(3, 2)或 add(undefined, 2))。

    剩余参数

    当我们不知道一个函数里会传递多少个参数时,就会用到 剩余参数

    function build(name: string, ...names: string[]) {
        return name + names.join("");
    }
    
    let buildFun: (x: string, ...y: string[]) => string = build;
    console.log(buildFun('hello', ', ', 'world', '!'));
    //hello, world!
    

    剩余参数会被当做个数不限的可选参数。 可以一个都没有,同样也可以有任意个。 编译器创建参数数组,名字是你在省略号( ...)后面给定的名字,你可以在函数体内使用这个数组。

    this

    当返回一个函数或将函数当做参数传递的时候,确定 this值会变的很难。

    let demo = {
        name: 'Demo',
        show: function() {
            console.log(this);
            return function() {
                console.log(this);
                console.log(this.name);
            }
        }
    }
    let d = demo.show();
    d();//undefined
    

    我们在对象的show方法里返回了一个函数。这个返回函数里面this已经变掉了,不再是当前对象。
    对象的show方法中的 this 打印出来是当前对象Object {name: "Demo"} 。它里面定义的返回函数里打印的 this 是一个 global(全局)对象,如果开启严格模式的话,会是 undefined

    通过使用ES6中的箭头函数可以解决这个问题,箭头函数能保存函数创建时的 this值,而不是调用时的值。

    let demo = {
        name: 'Demo',
        show: function() {
            console.log(this);
            return ()=> {
                console.log(this.name);
            }
        }
    }
    let d = demo.show();
    d();//Demo
    

    箭头函数会保存 创建这个箭头函数的当前对象 的this值。这时候鼠标放到箭头函数里面的this上会发现这个this是一个 any 类型,同时 this.name 也是一个 any 类型。这是因为 this来自对象里的函数表达式。

    可以用如下的解决办法提供一个显式的 this参数,处理this变成any类型。this参数是个假的参数,它出现在参数列表的最前面

    interface Ani {
        name: string;
        show(this: Ani): ()=> void;
    }
    let ani: Ani = {
        name: 'Ani',
        show: function(this: Ani) {
            return ()=> {
                console.log(this.name);
            }
        }
    }
    let a = ani.show();
    a();//Ani
    

    现在鼠标放到箭头函数的this上发现它的类型正确了,是Ani。

    重载

    让函数根据传入的不同参数类型,返回不同的值类型,需要用到重载。通过为同一个函数提供多个函数类型定义来进行函数重载。 编译器会根据这个函数定义列表去处理函数的调用。

    function Add(a: number, b: number): number;
    function Add(x: string, y: string): string;
    function Add(x, y): any {
        if (typeof x == 'number') {
            console.log(x + y);
        } else if (typeof x == 'string') {
            console.log(x + ' ' + y);
        }
    }
    Add(3, 5);//8
    Add('Hello', 'world!');//Hello world!
    

    我们给函数定义了两种类型,一个接收 number 类型参数,返回也是 number 类型;另一个接收 string类型参数,返回是 string 类型。
    通过重载,我们的函数既可以处理 number 类型参数的调用,又可以处理 string 类型参数的调用。

    相关文章

      网友评论

        本文标题:TypeScript 旅途4:函数

        本文链接:https://www.haomeiwen.com/subject/gfjxzxtx.html