• 深入理解TypeScript——文档篇之函数


    一、函数类型

    1. 定义函数类型

      // 函数式声明
      function add(x: number, y: number): number {
          return x + y;
      }
      
      // 由变量指向的匿名函数
      let myAdd = function(x: number, y: number): number { return x + y; };
      
    2. 完整函数类型

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

      通常需要将类型抽离成接口,形成规范。

    3. 推断类型

      函数定义赋值语句一边有类型。

      // myAdd has the full function type
      let myAdd = function(x: number, y: number): number { return x + y; };
      
      // The parameters `x` and `y` have the type number
      let myAdd: (baseValue: number, increment: number) => number =
          function(x, y) { return x + y; };
      

    二、可选参数、默认参数

    ​ ts中传递给一个函数的参数个数必须与函数期望的参数个数一致。

    1. 可选参数

      在TypeScript里我们可以在参数名旁使用 ?实现可选参数的功能。

      function buildName(firstName: string, lastName?: string) {
          if (lastName)
              return firstName + " " + lastName;
          else
              return firstName;
      }
      
      let result1 = buildName("Bob");  // works correctly now
      let result2 = buildName("Bob", "Adams", "Sr.");  // error, too many parameters
      let result3 = buildName("Bob", "Adams");  // ah, just right
      

      注意:可选参数必须跟在必须参数后面。

    2. 默认参数

      在TypeScript里,我们也可以为参数提供一个默认值当用户没有传递这个参数或传递的值是undefined时。 它们叫做有默认初始化值的参数。

      function buildName(firstName: string, lastName = "Smith") {
          return firstName + " " + lastName;
      }
      
      let result1 = buildName("Bob");                  // works correctly now, returns "Bob Smith"
      let result2 = buildName("Bob", undefined);       // still works, also returns "Bob Smith"
      let result3 = buildName("Bob", "Adams", "Sr.");  // error, too many parameters
      let result4 = buildName("Bob", "Adams");         // ah, just right
      

      在所有必须参数后面的带默认初始化的参数都是可选的,与可选参数一样,在调用函数的时候可以省略。

      function buildName(firstName: string, lastName?: string) {
          // ...
      }
      
      function buildName(firstName: string, lastName = "Smith") { // lastName为可选,调用时可省略
          // ...
      }
      

      与普通可选参数不同的是,带默认值的参数不需要放在必须参数的后面。 如果带默认值的参数出现在必须参数前面,用户必须明确的传入 undefined值来获得默认值。 例如,我们重写最后一个例子,让 firstName是带默认值的参数:

      function buildName(firstName = "Will", lastName: string) {
          return firstName + " " + lastName;
      }
      
      let result1 = buildName("Bob");                  // error, too few parameters
      let result2 = buildName("Bob", "Adams", "Sr.");  // error, too many parameters
      let result3 = buildName("Bob", "Adams");         // okay and returns "Bob Adams"
      let result4 = buildName(undefined, "Adams");     // okay and returns "Will Adams" 首个参数后有其他参数,则要取得默认值必须要传入undefined
      
    3. 剩余参数

      剩余参数会被当做个数不限的可选参数。

      function buildName(firstName: string, ...restOfName: string[]) {
        return firstName + " " + restOfName.join(" ");
      }
      
      let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
      
    4. this

      JavaScript里,this的值在函数被调用的时候才会指定。

      let deck = {
          suits: ["hearts", "spades", "clubs", "diamonds"],
          cards: Array(52),
          createCardPicker: function() {
              return function() {
                  let pickedCard = Math.floor(Math.random() * 52);
                  let pickedSuit = Math.floor(pickedCard / 13);
      
                  return {suit: this.suits[pickedSuit], card: pickedCard % 13};
              }
          }
      }
      
      let cardPicker = deck.createCardPicker();
      let pickedCard = cardPicker();
      
      alert("card: " + pickedCard.card + " of " + pickedCard.suit); // error 找不到this
      

      箭头函数能保存函数创建时的 this值,而不是调用时的值。

      let deck = {
          suits: ["hearts", "spades", "clubs", "diamonds"],
          cards: Array(52),
          createCardPicker: function() {
              // NOTE: the line below is now an arrow function, allowing us to capture 'this' right here
              return () => {
                  let pickedCard = Math.floor(Math.random() * 52);
                  let pickedSuit = Math.floor(pickedCard / 13);
      
                  return {suit: this.suits[pickedSuit], card: pickedCard % 13};
              }
          }
      }
      
      let cardPicker = deck.createCardPicker();
      let pickedCard = cardPicker();
      
      alert("card: " + pickedCard.card + " of " + pickedCard.suit);
      
    5. 重载

      方法是为同一个函数提供多个函数类型定义来进行函数重载。

      let suits = ["hearts", "spades", "clubs", "diamonds"];
      
      function pickCard(x: {suit: string; card: number; }[]): number;
      function pickCard(x: number): {suit: string; card: number; };
      function pickCard(x): any {
          // Check to see if we're working with an object/array
          // if so, they gave us the deck and we'll pick the card
          if (typeof x == "object") {
              let pickedCard = Math.floor(Math.random() * x.length);
              return pickedCard;
          }                                                                                                                                                                                                                                                            
          // Otherwise just let them pick the card
          else if (typeof x == "number") {
              let pickedSuit = Math.floor(x / 13);
              return { suit: suits[pickedSuit], card: x % 13 };
          }
      }
      
      let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
      let pickedCard1 = myDeck[pickCard(myDeck)];
      alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);
      
      let pickedCard2 = pickCard(15);
      alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);
      

      为了让编译器能够选择正确的检查类型,它与JavaScript里的处理流程相似。 它查找重载列表,尝试使用第一个重载定义。 如果匹配的话就使用这个。 因此,在定义重载的时候,一定要把最精确的定义放在最前面。(大几率事件)

  • 相关阅读:
    在登陆脚本中设置自动打开某个网页
    修改2k自动登陆的脚本
    COM组件和NT服务
    HRMS提示"HRMS服务器未注册或注册不正确"问题
    登录脚本
    vb的GUID生成算法
    WIN2000管理员密码的解密
    注册表中相等的项
    统一管理Windows 2000域中的服务
    深入挖掘Windows脚本技术
  • 原文地址:https://www.cnblogs.com/hackftz/p/13806382.html
Copyright © 2020-2023  润新知