首页 > 其他 > 详细

六、函数

时间:2019-09-07 00:35:42      阅读:107      评论:0      收藏:0      [点我收藏+]
普通定义
let a = 100;
function getNum(x,y){
  return a + x + y;
}
console.log(getNum(1,3))

为函数定义类型

function add(x: number, y: number): number{
  return x + y;
}
// 可以为函数体本身添加返回值类型,由于TS会根据返回语句自动推断出返回值类型,因此可以省略
let myAdd = function(x: number, y: number): number {
  return x + y;
}

完整的函数类型

函数类型包含两部分:

  • 参数类型
  • 返回值类型
// 完整的书写方式应该两个方面都提现出来
let meAdd: (x: number, y: number) => number = function(x: number, y: number): number {
  return x + y;
}

推断类型

函数定义时,如果赋值语句的一边指定了类型但另一边没有类型的话,TS会自动识别出类型

// 右边指定了类型
let typeAdd = function(x: number, y: number): number { return x + y; };
// 左边指定了类型
let typeAdd1: (baseValue: number, increment: number) => number = function(x, y) { return x + y; }

可选参数跟默认参数

  • TS中每个函数的参数都是必须的,传递给一个函数的参数个数必须与函数期望的参数个数一致
  • S中可以在参数名旁边使用?实现可选参数功能。可选参数必须跟在参数后面
  • TS中可以给参数提供一个默认值当用户没有传递这个参数或者传undefined时,使用默认值,默认参数的位置没有要求但是,如果带默认值的参数放在必须参数前面,用户必须明确的传入undefined来获取默认值
  • 可选参数或者默认参数在调用时都可以省略
function buildName(firstName: string, lastName: string){
  return firstName + ‘ ‘ + lastName;
}
// let resutl1 = buildName(‘Bob‘); // error 参数个数不够
// let result2 = buildName(‘Bob‘, ‘Admas‘, ‘Sr‘); // error 参数个数超出
let result3 = buildName(‘Bob‘, ‘Admas‘); // Ok
// 可选参数
function buildMyName(firstName: string, lastName?: string){
  if(lastName){
    return firstName + ‘ ‘ + lastName;
  }else{
    return firstName;
  }
}
let res1 = buildMyName(‘Bob‘); // Ok
let res2 = buildMyName(‘Bob‘, ‘Admas‘); // Ok
// let res3 = buildMyName(‘Bob‘, ‘Admas‘, ‘Sr‘); // error 参数超出
// 设置默认值
function buildDefaultName(firstName: string, lastName = "Smith"){
  return firstName + ‘ ‘ + lastName;
}
let rest1 = buildDefaultName(‘Bob‘); // Ok
let rest2 = buildDefaultName(‘Bob‘, undefined); // Ok
// let rest3 = buildDefaultName(‘Bob‘, ‘Admas‘, ‘Sr‘); // error 参数多余
let rest4 = buildDefaultName(‘Bob‘, ‘Admas‘); // Ok

剩余参数

TS中可以把所有参数收集到一个变量里:用...表示
剩余参数会被当做个数不限的可选参数,可以是0到多个

function buildOtherName(firstName: string, ...restOfName: string[]){
  return firstName + ‘ ‘ + restOfName.join(‘ ‘);
}
let ohters = buildOtherName(‘Bob‘, ‘Admas‘, ‘jjzhang‘,‘hahaa‘, ‘kdddd‘);

函数中的this

  • 在JS中,只有在函数被调用的时候才会指定this的值
  • 顶级的非方法式调用会将this视为window对象
  • 箭头函数能保存函数创建时的this值,而不是调用时的值
  • 如果设置了noImplicitThis标记,TS会指出当this为window时,this的类型为any
let deck = {
  suits: [‘hearts‘, ‘spades‘, ‘clubs‘, ‘dismonds‘],
  cards: Array(52),
  createCardPicker: function() {
    return function() {
      let pickedCard = Math.floor(Math.random() * 52);
      let pickedSuit = Math.floor(pickedCard / 3);
      // 此时this指向window
      return { suit: this.suits[pickedSuit], card: pickedCard % 13 };
    }
  },
  createCardPicker1: function() {
    return () => {
      let pickedCard = Math.floor(Math.random() * 52);
      let pickedSuit = Math.floor(pickedCard / 3);
      // 此时this.suits的类型为any类型,因为this来自对象字面量里的函数表达式
      return { suit: this.suits[pickedSuit], card: pickedCard % 13 };
    }
  }
}

let cardPicker = deck.createCardPicker1();
let pickedCard = cardPicker();
console.log(‘card: ‘ + pickedCard.card + ‘ of ‘ + pickedCard.suit);
// this参数
interface Card {
  suit: string;
  card: number;
}
interface Deck {
  suits: string[];
  cards: number[];
  createCardPicker(this: Deck): () => Card;
}
let deck1: Deck = {
  suits: [‘hearts‘, ‘spades‘, ‘clubs‘, ‘dismonds‘],
  cards: Array(52),
  createCardPicker: function(this: Deck) {
    return () => {
      let pickedCard = Math.floor(Math.random() * 52);
      let pickedSuit = Math.floor(pickedCard / 3);
      // 此时this的类型就不是any而是Deck实例了
      return { suit: this.suits[pickedSuit], card: pickedCard % 13 };
    }
  }
}
let cardPicker1 = deck1.createCardPicker();
let pickedCard1 = cardPicker1();
console.log(‘card: ‘ + pickedCard1.card + ‘ of ‘ + pickedCard1.suit);

重载

  • 为同一个函数提供多个函数类型定义来进行函数重载,编译器会根据这个列表去处理函数的调用
  • TS查找重载列表,尝试使用第一个重载定义,如果匹配就用这个不匹配继续向下查找,所以在定义重载时,需要把最精确的定义放在最前面
  • TS中函数重载没有任何运行时开销,他只允许你记录希望调用的函数方式,并且编译器会检查其余代码
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 {
  if(typeof x == ‘object‘){
    let pickCard = Math.floor(Math.random() * x.length);
    return pickCard;
  }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 pickedCard3 = myDeck[pickCard(myDeck)];
console.log("card: " + pickedCard3.card + " of " + pickedCard3.suit);

let pickedCard2 = pickCard(15);
console.log("card: " + pickedCard2.card + " of " + pickedCard2.suit);

六、函数

原文:https://blog.51cto.com/14533658/2436005

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!