【问题标题】:How to access property in extended class in Coffeescript?如何访问 Coffeescript 扩展类中的属性?
【发布时间】:2014-02-19 00:57:21
【问题描述】:

我想在 if 语句中使用@Type,但它似乎无法识别@Type。有没有办法获得@Type 以便我可以在超类中使用它?

class opponent
    constructor: (ID, Level, Name) ->
        @ID = ID
        @Level = Level
        @Name = Name
        @Health = if @Level is 1
            @Level * 5 
        else if 2 <= @Level <= 4
            (@Level * 6) - (@Level * 2)  
        @Luck = if @Type is "Snake"
            Math.ceil(@Level * 1.25) + 5
        else
            Math.ceil(@Level * 1.25)
        @attackDamage = 0
        @defenseDoubled = false;
        @Poisoned = false;
        @Burned = false;
        @Frozen = false;

    @defend: ->
        @Defense *= 2
        @DefenseDoubled = true;
    @undefend: ->
        @Defense /= 2
        @DefenseDoubled = false;

class Snake extends opponent
    @Type: "Snake"

【问题讨论】:

  • 为什么Snake 不设置@Health 本身?父类不应该知道任何可能的扩展。
  • @hpaulj 我试图避免这种情况,因为我将制作更多从对手扩展的类,但我想这样做可能更容易
  • @Type: "Snake" 行创建了一个(借用 Java 术语)静态变量。如果你希望它是非静态的,你可以使用Type: "Snake"。你不这样做有什么原因吗?

标签: javascript class if-statement coffeescript extends


【解决方案1】:

这不能回答您的问题(关于如何使子类属性对父类可见),但它应该产生相同的结果 - 以一种易于扩展的方式。您可以添加更多子类,而无需每次返回并更改 opponent

class opponent
    constructor: (ID, Level, Name) ->
        @ID = ID
        @Level = Level
        @Name = Name
        @Health = if @Level is 1
            @Level * 5 
        else if 2 <= @Level <= 4
            (@Level * 6) - (@Level * 2)  
        @Luck = Math.ceil(@Level * 1.25)
        @attackDamage = 0
        # ...

class Snake extends opponent
    constructor : (ID, Level, Name) ->
      # use parent constructor to create the object
      # and then customize the values for this class
      super
      @Luck = Math.ceil(@Level * 1.25) + 5

【讨论】:

  • 为了使其更简单和面向未来,您将在 opponent 类中实现 @Luck 计算,并且只定义某种 luck 修饰符 i> 在子类中,这样子类就不用担心运气是如何计算的了。
【解决方案2】:

您可以使用constructor property 进入“课堂”:

返回对创建实例原型的Object 函数的引用。

所以如果s 是一条蛇,那么s.constructor 就是Snake。这意味着您可以执行以下操作:

class A
    m: -> console.log(@constructor.type)

class B extends A
    @type = 'B'

class C extends A
    @type = 'C'

(new B).m()
(new C).m()

并在控制台中获取'B''C'

演示:http://jsfiddle.net/ambiguous/bE6jh/

在您的特定情况下,您需要查看方法中的 @constructor.Type 来了解类型。

【讨论】:

    【解决方案3】:

    您的代码不起作用,因为在父类中,您引用了一个实例变量 @Type,但在 Snake 子类中,您定义了一个类变量 @Type: "Snake"

    要将Type 变量声明为实例变量,请在不带@ 符号的情况下声明它:

    class Snake extends opponent
      Type: "Snake"
    

    为了进一步扩展 hpaulj 的 answer - 你总是希望你的代码保持 DRY,所以计算 @Luck 属性的逻辑应该只在父类中定义。考虑以下示例:

    class opponent
      constructor: ( args... ) ->
      # ... your logic
      @Luck = Math.ceil(@Level * 1.25) + ( @LuckFactor? or 0 )
    
    class Snake extends opponent
      LuckFactor: 5
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-06
      • 2015-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多