2012-02-13 31 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 2012-02-13 17:59:11

+0

@Naatan它不是一個黑客。你可以在coffeescript中使用普通的構造函數或原型。 – 2012-02-13 22:30:21

+0

我的意思是說,這是一種黑客,因爲您正在使用該語言的方式並非意圖。 – Naatan 2012-02-14 18:12:43

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抽象(沒有什麼比原型使用的一個漂亮包裝包裹更多)和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 2012-02-14 18:14:58

+0

@Naatan:但是這不會讓你的JavaScript版本成爲黑客嗎?畢竟,你將函數直接添加到一個對象,並且沒有任何類似的東西在望。我不是想在這裏開始戰鬥,每種語言都有它醜陋的廢話的小角落,通常有一個標準的成語(或十)用於處理這些角落。 – 2012-02-14 18:38:19

+0

@ muistooshort你是對的..JavaScript教會了我一些不好的習慣。 – Naatan 2012-02-14 18:52:48