010--TypeScript里面的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()

console.log('card: ' + pickedCard.card + ' of ' + pickedCard.suit)
//编译后出错,因为上述的this指向global 
//改进的方法可以把上述函数改成箭头函数
let deck = {
  suits: ['hearts', 'spades', 'clubs', 'diamonds'],
  cards: Array(52),
  createCardPicker: function() {
    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()

console.log('card: ' + pickedCard.card + ' of ' + pickedCard.suit)

实际上编译后是吧this存起来了

现在还有一个问题这个this在这个函数类型检测里面是any,有一个方法是把这个this直接指向void,在函数里面这个this则不可用

完善函数

interface Card {
  suit: string
  card: number
}

interface Deck {
  suits: string[]
  cards: number[]
     
  createCardPicker(this: Deck): ()=> Card
}
let deck: Deck = {
  suits: ['hearts', 'spades', 'clubs', 'diamonds'],
  cards: Array(52),
  createCardPicker: function(this: Deck) {
    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()

console.log('card: ' + pickedCard.card + ' of ' + pickedCard.suit)

this在回调函数里面的指向

interface UIElement {
  addClickListener(onclick: (this: void, e: Event) => void) :void
}

class Handler {
  type: string
  onclickBad(this: Handler, e: Event){
    this.type = e.type
  }
}

let h = new Handler()

let uiElement: UIElement = {
  addClickListener(){

  }
}

uiElement.addClickListener(h.onclickBad)//报错this类型不兼容,因为上面我们定义的this是void
//如果我们既想满足接口的约定,又想使用this.type = e.type,可以使用箭头函数
// class Handler {
//   type: string
//   onclickBad = (e: Event)=>{
//     this.type = e.type
//   }
// }

重载

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 (Array.isArray(x)){
    let pickedCard = Math.floor(Math.random() * x.length)
    return pickedCard
  } 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)];
console.log('card: ' + pickedCard1.card + ' of ' + pickedCard1.suit)
//card: 4 of hearts
let pickedCard2 = pickCard(15)
console.log('card: ' + pickedCard2.card + ' of ' + pickedCard2.suit)
//card: 2 of spades

2019-05-28  17:45:28

工欲善其事,必先利其器
原文地址:https://www.cnblogs.com/ccbest/p/10939072.html