关于typescript中function的this参数

Js中的this指向出错是开发中比较常见的错误,幸运的是,在typescript中使用this时,当出现错误它能够立即给你错误提示。

以官网的示例为例

let deck = {
  suits: ['hearts', 'spades', 'clubs', 'diamonds'],
  cards: Array(52),
  createCardPicker() {
    return function() {
      let pickedCard = Math.floor(Math.random() * 52);
      let pickedSuit = Math.floor(pickedCard / 13);

      return { suit: this.suits[pickedSuit], card: pickedCard % 13 };
    };
  }
};

这里createCardPicker返回的匿名函数的this其实指向的是window(在严格模式下为undefined)。在typescript中,它会提示你this具有隐式类型any。所以,为了保证this的指向正确,可以将createCardPicker中的function更换成箭头函数。

let deck= {
  // ...
  createCardPicker() {
    return () => {
      // ...
      return { suit: this.suits[pickedSuit], card: pickedCard % 13 };
    };
  }
};

我们,还可以在函数参数的第一个参数指定this属于哪一个对象下,指定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(this: Deck) {
    return () => {
      let pickedCard = Math.floor(Math.random() * 52);
      let pickedSuit = Math.floor(pickedCard / 13);

      return { suit: this.suits[pickedSuit], card: pickedCard % 13 };
    };
  }
};

那么,这里的this确定是Deck对象并且也只能是Deck对象,当其他对象调用就会给出错误提示。

既然这样,我们还可以createCardPicker提出到外面成一个单独的函数。

function createCardPicker(this: Deck): () => Card {
  return () => {
    let pickedCard = Math.floor(Math.random() * 52);
    let pickedSuit = Math.floor(pickedCard / 13);

    return { suit: this.suits[pickedSuit], card: pickedCard % 13 };
  };
}

let deck: Deck = {
  suits: ['hearts', 'spades', 'clubs', 'diamonds'],
  cards: Array(52),
  createCardPicker
};

我们也可以将this声明为void,表示方法中不能使用this

function createCardPicker(this: void) {
  return () => {
    // 报错: 类型“void”上不存在属性“name”。
    this.name = 'leevare';
  };
}

总结

在Typescript中,只能在function的第一个参数添加this约束,对this进行约束后,则表示只能在约束的对象上调用,否则将会出错。

如果您觉得本文对您有用,欢迎捐赠或留言~
微信支付
支付宝

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注