请问老师关于this规范
来源:3-19 函数 - this+ 重载

hy_wang
2019-04-28
请问一下老师关于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),
// NOTE: 函数现在显式指定其被调用方必须是 deck 类型
createCardPicker: function (this: Deck) {
return function (this:Deck) {
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指向Deck,但是这个demo明明this并没有指向Deck而是Winodw,可是请问老师ts也没有提示错误。编译也通过。只是执行js报错。
请问老师关于this规范有什么作用?他什么时候会规范?
写回答
1回答
-
因为你只是显示的指明 this 的类型,但它实际的类型需要运行时来决定。记住声明并不能决定运行时的值。这里的正确姿势是内部使用箭头函数,而我们给 createCardPicker 的 this 加上 Deck 类型,是因为我们知道运行时的时候 createCardPicker 中的 this 是 Deck 类型,而 TypeScript 不知道,所以我们告诉它。
再举个极端例子,即使你显示给 createCardPicker 的 this 加上 Deck 类型,内部也使用箭头函数,但是如果运行时我们把 deck.createCardPicker 的 this 修改了,也会报错,你可以试试,在箭头函数的情况下,我们修改调用的代码。
let cardPicker = deck.createCardPicker.call({})
let pickedCard = cardPicker()
这样也会运行时报错,所以显示声明类型的意义是我们知道运行时应该是什么样的,它是来配合我们运行时用的,但它并不能决定我们运行时的行为,就 this 而言,它在运行时是什么值还是取决于我们如何去调用它。142019-04-28
相似问题