2012-02-13 7 views
1

のCoffeeScriptで次のように記述する方法を把握しよう:CoffeeScriptのクラスポインタ?

var foo = new function() 
{ 

    var $this = this; 

    $("#foo").click(this.clicked); 

    this.clicked = function() 
    { 
     $this.alert($(this).text()); 
    }; 

    this.alert = function(message) 
    { 
     alert(message); 
    }; 

}; 

残念ながら、私は「これは」明らかに文脈認識していない、クラスポインタにアクセスする方法のCoffeeScriptで私の人生のために把握することはできません呼び出し先が渡す変数を指すことがよくあります。だから私はCoffeeScriptで上記のスクリプトを書く方法がありません。

アドバイスはありますか?ドキュメントで役に立つものが見つからない場合は、@ポインタを持っていますが、現在のコンテキストから "this"ポインタを使用するだけで、役に立たなくなります。

答えて

3

コンストラクタ内のメソッドを直接@に追加できます同じ効果を達成するために:

class C 
    constructor: -> 
     $this = @ 
     @clicked = -> 
      console.log @ 
      $this.alert 'pancakes' 
    alert: (m) -> 
     console.log m 

c = new C 
c.clicked() 
c.clicked.call window​​​​​ 

デモ:http://jsfiddle.net/ambiguous/Y8ZBe/

あなたは通常bound methodといえ、このような状況では、「イベント」引数を使用することができるだろう:

class C 
    clicked: (ev) => 
     @alert(ev.target.value) 
    alert: (m) -> 
     console.log m 

c = new C 
c.clicked(target: { value: 'pancakes' }) 
c.clicked.call window, target: { value: 'pancakes' } 

この種のことは、通常、jQuery(または同様の)コールバックに現れ、通常、バインドされた関数を使用できるように、ターゲット "this"を明示的に識別するイベント引数を持ちます。

デモ:http://jsfiddle.net/ambiguous/LafV2/

+0

ありがとう、私はコンストラクタを使用すると思わなかったことを除いて、最初のオプションで行ったのと同様のものを試していました。それでもCSがネイティブにサポートすべき何かを達成するためのハックです。これは残念です。:\ – Naatan

+0

@Naatanハックではありません。普通のコンストラクタ関数やプロトタイプをcoffeescriptで使うことができます。 –

+0

私は、それが意図されていない方法で言語を使用しているという意味でハックだと言っていました。 – Naatan

2

のCoffeeScriptはまだjavascriptのです。 thisの制限が適用されます。

foo = -> 
    self = this 
    @clicked = -> 
     self.alert $(this).text() 
    @alert = (message) -> 
     alert message 
    $('#foo').click @clicked 

まだプロトタイプを使用する必要があります(javascriptでも)。あなたはそれに関数をバインドすることができ=>脂肪の矢印は、現在のコンテキストだ(しかし、あなたは要素の参照を失う)付:

foo = -> 
    $('#foo').click (e) => 
     @clicked(e.target) 

foo::clicked = (el) -> 
    @alert $(el).text() 

foo::alert = (message) -> 
    alert message 

それともclass抽象化(きれいにパッケージに包まれたプロトタイプの使用量よりも多くのNothing)を使用してjQuery.proxy

class Foo 
    constructor: -> 
     $('#foo').click $.proxy @clicked, this 
    clicked: (e) -> 
     @alert $(e.target).text() 
    alert: (message) -> 
     alert message 

$.proxy @clicked, thisは、近代的なブラウザで@clicked.bind @に置き換えることができます/エンジン(Function.prototype.bindを参照してください)。

+0

オブジェクト内で関数を追加するとクラスの抽象化が失敗します。あなたがあなた自身を定義しない限り、クラス内のどこにでもアクセス可能なクラスポインタが存在しないということです。その場合、あなたは言語の目的を部分的に無視しています。 – Naatan

+0

@Naatan:しかしJavaScriptのバージョンをハックにするのではないでしょうか?結局のところ、あなたはオブジェクトに直接関数を追加していますし、クラスには何も見えません。私はここで戦いを始めようとはしていないが、すべての言語には不快なナンセンスの醜いコーナーがあり、通常はそのコーナーを扱うための標準的なイディオム(または10)がある。 –

+0

@muistooshortあなたは正しいです..JavaScriptはいくつかの悪い習慣を教えてくれました。 – Naatan