【问题标题】:How to handle 'this' in typescript/js ? need to convert Python code to Typescript如何在 typescript/js 中处理“this”?需要将 Python 代码转换为 Typescript
【发布时间】:2017-12-16 18:38:53
【问题描述】:

我有这个用 python 编写的简单代码来创建一个小的 纸牌游戏,我想用打字稿做同样的事情,但我 在我的 Typescript 主课中遇到“this”的大问题 这是原始的python类:

class deck:
    card_type=['Hearts ','Diamonds','Spades','Clubs']
    card_rank=[2,3,4,5,6,7,8,9,10,'A','J','Q','K']
    full_deck=[]

    def build_deck(self):
        single={}
        for card in self.card_type:
            for n in self.card_rank:
                single={n: card}
                self.full_deck.append(single)
        shuffle(self.full_deck)


    def reshuffle (self):
        print('Re-shuffling again!')
        shuffle(self.full_deck)


    def choose_card(self):
        chosen=choice(self.full_deck)
        the_index= self.full_deck.index(chosen)
        self.full_deck.pop(the_index)

        return chosen

    def pick_hand(self, number_of_cards):
        hand=[]
        new_card={}

        for i in range(number_of_cards):
            new_card = self.choose_card()
            hand.append(new_card)

        return hand

在我的主游戏文件中,我做了这样的事情:

from classes import deck

deck1= deck()
deck1.build_deck()
my_hand=deck1.pick_hand(3)
compu_hand=deck1.pick_hand(3)

但是当我尝试在类型脚本中创建一个类似的类时,我写了以下内容:

export class deck {

  single_card: {
    cType: string;
    cNumber: any;
  };

  fullDeck: any[] = [];
  card_type=['Hearts ','Diamonds','Spades','Clubs'];
  card_rank=[2,3,4,5,6,7,8,9,10,'A','J','Q','K'];

  shuffle() {
    let counter = this.fullDeck.length;

    // While there are elements in the array
    while (counter > 0) {
        // Pick a random index
        let index = Math.floor(Math.random() * counter);

        // Decrease counter by 1
        counter--;

        // And swap the last element with it
        let temp = this.fullDeck[counter];
        this.fullDeck[counter] = this.fullDeck[index];
        this.fullDeck[index] = temp;
    }

    // return this.fullDeck;
  }


  buildDeck (){

    for (let t in this.card_type) {
      for ( let n in this.card_rank) {
        this.single_card.cType = this.card_type[t];
        this.single_card.cNumber = this.card_rank[n];
        this.fullDeck.push(this.single_card);
        console.log(this.single_card);
      }
    }
    // this.shuffle() 

  }

}

当我尝试像这样使用主“ts”文件中的类时:

import {deck} from './myclasses'

$(document).ready (function(){
    let deck1= new deck;
    deck1.buildDeck();
});

console.log 调用返回同样的错误:

jQuery.Deferred 异常:无法设置未定义的属性“cType” TypeError:无法设置未定义的属性“cType” 在deck.buildDeck (file:///run/media/Work/HTML_Porjects/Game_TS/built/myclasses.js:132:44)

它是如何未定义的? 我需要做什么才能使 Typescript 代码像 Python 代码一样工作?

提前致谢...

【问题讨论】:

  • 抱歉,我给出了一个我认为可能大错特错的答案。
  • 但您似乎在奇怪地使用single_card。您不是将其定义为数据类型吗?那么为什么要像对象属性一样使用呢?
  • 感谢您的回复,我确实尝试了箭头功能它不起作用
  • 抱歉,您是什么意思? single_card 是甲板类的属性
  • 看起来不像。它没有像所有其他属性一样出现在this 中。它必须有一些语法不正确的东西。但我不知道打字稿;)

标签: javascript python python-3.x typescript this


【解决方案1】:

错误只是表明single_card 未定义,它是:

class deck {

  single_card: {
    cType: string;
    cNumber: any;
  };

  // …
}

这将在 TypeScript 类上声明属性 single_card,以便当您引用该类型对象的 single_card 属性时(例如,在执行 this.single_card 时),编译器将接受。然而,这样做不会真正地将该类型的对象分配给该对象。因此,对于已编译的 JavaScript(其中类型信息已被删除),该属性不存在,因为您从未分配给它。您可以通过查看compiled JavaScript there 轻松验证这一点。

因此,您首先需要为single_card 分配一些东西,就像您在 Python 版本中所做的那样:

this.single_card = {}

但是,如果您实际查看您的 Python 版本,single_card 不是对象的成员,它实际上没有任何意义。您正在使用它来构造卡片对象,然后将其添加到 fullDeck 数组中。在 Python 中,它是一个局部变量,所以你也应该在 TypeScript 版本中使它成为一个局部变量:

buildDeck() {
  for (const t of this.card_type) {
    for (const n of this.card_rank) {
      const single_card = {
          cType: this.card_type[t],
          cNumber: this.card_rank[n]
      };
      this.fullDeck.push(single_card);
    }
  }
}

顺便说一句。您还想在那里使用for…of 循环而不是for…in

您还应该考虑正确输入fullDeck。现在它是一个any 的数组,所以它可以存储任何对象。但是你想要做的实际上只是将看起来像single_card 的对象保留在其中。所以考虑为此声明一个类型:

interface SingleCard {
    cType: string;
    cNumber: any;
}

然后,你可以正确输入fullDeck

fullDeck: SingleCard[] = [];

【讨论】:

  • 您的回答是我非常想发生的事情,但缺乏了解实际 TS 语法的知识。不错的答案
  • 非常感谢你的详细回答,我同意你的观点,single_card 不应该是对象的成员,它不是,但在我失败的尝试中,我把它移了进去,但现在我把它移了出来.至于您的建议,它实际上修复了错误,但由于某种原因,full_deck 是最后一张卡的 52 项! 52副本同一个对象!当我尝试 console.log 循环内的对象 single_card 时,我得到 52 张不同的卡片,但列表 full_deck 仅填充了最后一张卡片!为什么会这样?
  • 如果你一直推送同一个single_card 对象,并且只是更新它的属性,那么所有的对象都是一样的。您应该像我在回答中显示的那样在每次迭代中创建一个新对象(或者至少在分配其属性之前执行single_card = {})。
  • 非常感谢!终于成功了……顺便说一句,我讨厌 JS 和 Typescript!
  • 虽然这不是 JS/TS 特定的,但如果您在 Python 解决方案中使用实例成员,您会遇到完全相同的问题 ;)
猜你喜欢
  • 2019-05-24
  • 2016-11-05
  • 1970-01-01
  • 2021-10-27
  • 2021-12-24
  • 2022-06-15
  • 2019-05-20
  • 1970-01-01
  • 2020-02-13
相关资源
最近更新 更多