2016-12-22 2 views
0

私はcoffescriptを勉強しています。クラスのすべてのインスタンス化中にインスタンスメソッド(@generate_human)を実行したいが、関数が存在しないというエラーが出る。代わりにメソッドをクラスメソッドに変更すると、すべてが機能します。何が起こっている?クラスレベルでインスタンスメソッドが機能しないのはなぜですか?

class Human # As biological creature 
    constructor: (@given_sex = null, 
        @age = null, # Age of the person 
        @max_age = 85) -> # Maximum allowed age of the person during person generation 


     _alive = true 

     alive: -> 
      @_alive 

     dead: -> 
      not @alive() 

     has_died: -> 
      @_alive = false 

     _available_sexes: {0: 'female', 1: 'male'} 

     sex: -> 
      _sex = @_available_sexes[@given_sex] 

     generate_human: -> 
      @_alive = true 
      if @age is null 
       @age = Math.floor(Math.random() * @max_age) 
      if @given_sex is null 
       @given_sex = Math.floor(Math.random() * 2) 
      else if @given_sex not in [0,1] 
       n = @given_sex 
       err = 'Invalid sex value: ' + n 
       console.log(err) 
       throw new Error(err) 

     @generate_human() # In JavaScript this line throws an error that function 'this.generate_human()' does not exist 

h = new Human() 

答えて

0

@(AKA this)はクラス自体です。あなたがこれを言うとき:@m()

class C 
    @m() 

@はクラス自体ではなく、クラスのインスタンスを参照します。あなたがJavaScriptのバージョンを見れば、あなたは何が起こっているかが表示されるはずです。

var C = (function() { 
    function C() {} 
    C.m(); // <---------- This is the @m() call. 
    return C; 
})(); 

このラインアップの構文でクラスメソッドを定義するために:

class C 
    @m: -> 

このJavaScriptを次のようになります。

var C = (function() { 
    function C() {} 
    C.m = function() {}; // <--------- Here is the class method. 
    return C; 
})(); 

インスタンスの作成時にメソッドを実行する場合は、constructor

で呼び出します。

_alive = trueにもCoffeeScriptが何をしているのか、実際にはprivate class variable of sortsというデフォルトの@_aliveというインスタンス変数は定義されていません。代わりに_alive: trueが必要です。

また、CoffeeScriptの空白と非常に慎重で一致している必要があります。ばらつきや矛盾が発生すると、奇妙で​​不思議なエラーが発生する可能性があります。例えば、あなたのconstructor定義のためにそのフォーマットに対してお勧めしたいと思います。すべてのメソッドが同じインデントレベルにある場合は、より良い時間を得ることができます。

+0

私の '@generate_human()'とあなたとの相違点は見当たりません。それらはどちらも 'コンストラクタ'の下で呼び出され、それを呼び出す唯一の合理的な場所です。私の意見では、問題はこのメソッドが定義されている場所です: '@generate_human()'が例外をスローするよりも自分のコードでコンストラクタの中で定義した場合です。私が 'コンストラクタ'の外で定義すると、呼び出しは成功し、なぜ私が最初に書いた方法で動作しないのか分かりません(私はコンストラクタでメソッドを定義し、すぐに呼び出します)。私のコードを変更して、 'generate_human: - >'コンストラクタ内で動作するようにしてください。 –

+0

だから、実際にはすべてのものを 'コンストラクタ'の中に入れようとしていますか?私はインデントがcopy'n'pasteエラーであると仮定しました。構造体が意味をなさないため、クラスの一部になりたい場合は、コンストラクタの外にあるはずです。すべてが 'コンストラクター'の中にある場合、何もしません。オブジェクトリテラルを定義して完全に無視するのと同じです。 –

関連する問題