• TypeScript学习笔记(四):函数


    这篇笔记我们来看看TypeScript中的函数。

    函数类型

    在JavaScript中存在两种定义函数的方法,如下:

    1 //命名函数
    2 function add(x, y) {
    3     return x+y;
    4 }
    5 
    6 //匿名函数
    7 var myAdd = function(x, y) { return x+y; };

    在TypeScript中对应的写法如下:

    1 function add(x: number, y: number): number {
    2     return x+y;
    3 }
    4 
    5 var myAdd = function(x: number, y: number): number { return x+y; };

    而TypeScript中对函数的类型也可以定义,比如我们上面的myAdd没有定义类型,则可以将任意类型的函数赋值给它,当然赋值函数以外的东西也可以,这当然是不好的一种做法,我们看看下面的另外一种写法:

    var myAdd: (baseValue:number, increment:number)=>number = 
        function(x: number, y: number): number { return x+y; };

    这里我们将myAdd定义为必须是函数,同时必须是带有两个number参数返回值为number的函数,其它类型的函数赋值给myAdd会报错。

    定义函数类型

    看到这里你是不是焕然大悟了,这不就是C#的委托么?

    如果我们在使用到函数类型的地方都采用上面的写法会比较麻烦,所以可以先定义一个函数类型,在要使用到该类型的地方直接定义为该函数的类型即可,如下:

     1 /**
     2  * 这里可以看做 C# 中的委托.
     3  */
     4 interface IProgressHandler
     5 {
     6     /**
     7      * 进度报告方法.
     8      * @param progress 进度.
     9      * @returns {} 无.
    10      */
    11     (progress:number):void;
    12 }
    13 
    14 class Loading
    15 {
    16     private _progressHandler:IProgressHandler;
    17 
    18     Load(url:string, callback:IProgressHandler)
    19     {
    20         this._progressHandler = callback;
    21         //加载完毕
    22         this._progressHandler(1.0);
    23     }
    24 }
    25 
    26 function run()
    27 {
    28     var load: Loading = new Loading();
    29     load.Load("http://xxx/", function(p:number):void
    30     {
    31         alert("加载:" + p);
    32     });
    33 }
    34 
    35 run();

    可选和默认参数

    可选参数,表示该参数可以填写也可以不填写,使用?:表示,如下:

     1 function buildName(firstName:string, lastName?:string)
     2 {
     3     if(lastName)
     4         return firstName + " " + lastName;
     5     else
     6         return firstName;
     7 }
     8 
     9 alert(buildName("LiLie"));
    10 alert(buildName("Meimei", "Han"));

    没有提供实参则lastName为undefined。

    默认参数表示不填该参数则使用提供的默认值,如下:

    1 function buildName(firstName:string, lastName:string = "Wang")
    2 {
    3     return firstName + " " + lastName;
    4 }
    5 
    6 alert(buildName("LiLie"));//LiLie Wang
    7 alert(buildName("Meimei", "Han"));//Meimei Han

    对象参数类型

    我们看一下下面的写法:

    function getArea(quad:Object)
    {
        return quad["width"] * quad["height"];
    }
    
    alert(getArea({10, height:20}));

    这种写法存在一个问题,如果传入的实参没有width或height时运行时会报错但编译时不会报错,那么如何才能在编译时就进行类型判断呢?

    一般其它语言都是使用接口来解决这个问题,但是TypeScript有一种更快捷的方法实现,如下:

    1 function getArea(quad:{number, height:number})
    2 {
    3     return quad.width * quad.height;
    4 }
    5 
    6 alert(getArea({10, height:20}));

    同时也支持可选参数,但不支持默认参数,如下:

     1 function getArea(quad:{number, height?:number})
     2 {
     3     if (quad.height == undefined)
     4     {
     5         quad.height = 10;
     6     }
     7     return quad.width * quad.height;
     8 }
     9 
    10 alert(getArea({10}));

    可变参数

    可变参数表示可以任意填写任意参数,如下:

    1 function buildName(firstName:string, ...restOfName:string[])
    2 {
    3     alert(restOfName.length);
    4     return firstName + "," + restOfName.join(",");
    5 }
    6 
    7 alert(buildName("LiLie"));
    8 alert(buildName("LiLie", "MeimeiHan"));
    9 alert(buildName("LiLie", "MeimeiHan", "LinTao", "LaoWang"));

    Lambda

    简写的匿名函数,我们已上门的例子来看:

     1 /**
     2  * 这里可以看做 C# 中的委托.
     3  */
     4 interface IProgressHandler
     5 {
     6     /**
     7      * 进度报告方法.
     8      * @param progress 进度.
     9      * @returns {} 无.
    10      */
    11     (progress:number):string;
    12 }
    13 
    14 class Loading
    15 {
    16     private _progressHandler:IProgressHandler;
    17 
    18     Load(url:string, callback:IProgressHandler)
    19     {
    20         this._progressHandler = callback;
    21         //加载完毕
    22         alert(this._progressHandler(1.0));
    23     }
    24 }
    25 
    26 function run()
    27 {
    28     var load: Loading = new Loading();
    29     load.Load("http://xxx/", p => {
    30         alert("加载:" + p);
    31         return "Hello Lambda!";
    32     });
    33 }
    34 
    35 run();

    TypeScript的Lambda使用和C#中一致。

    Lambda和this

    我们看一下这个例子:

    1 var messenger = {
    2     message: "Hello World",
    3     start: function() {
    4         setTimeout(() => { alert(this.message); }, 3000);
    5     }
    6 };
    7 messenger.start();

    编译后的js如下:

     1 var messenger = {
     2     message: "Hello World",
     3     start: function () {
     4         var _this = this;
     5         setTimeout(function () {
     6             alert(_this.message);
     7         }, 3000);
     8     }
     9 };
    10 messenger.start();

    更多消息可以查看:http://www.codebelt.com/typescript/arrow-function-typescript-tutorial/

    重载

    TypeScript的函数支持重载,同名函数可以根据参数类型及数量的不同来执行不同的逻辑,不过定义重载函数和其它语言稍微不同:在TypeScript中需要先写一些同名的函数声明,然后在一个同名函数里写出实现,而且需要自己判断参数类型(比较鸡肋):

     1 function attr(name: string): string;
     2 function attr(name: string, value: string): Accessor;
     3 function attr(map: any): Accessor;
     4 
     5 function attr(nameOrMap: any, value?: string): any {
     6     if (nameOrMap && typeof nameOrMap === "object") {
     7         // handle map case
     8     }
     9     else {
    10         // handle string case
    11     }
    12 }
  • 相关阅读:
    C++ 黑白棋AI minimax+alphabeta剪枝
    BZOJ2839 集合计数 容斥
    BZOJ2287 消失之物
    CF235B Let's Play Osu! 期望DP
    线性基
    [HAOI2008]糖果传递 结论题
    [HAOI2007]上升序列
    线性筛及线性递推欧拉函数
    Codeforces 1064D/1063B Labyrinth
    洛谷P2120 [ZJOI2007]仓库建设 斜率优化DP
  • 原文地址:https://www.cnblogs.com/hammerc/p/4908984.html
Copyright © 2020-2023  润新知