2012-02-13 3 views
1

: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에서 위의 스크립트를 작성하는 방법은 없습니다.

어떤 조언이 필요합니까? 설명서에서 유용한 것을 찾을 수 없지만 @ 포인터가 있지만 현재 컨텍스트의 "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

커피 스크립트는 여전히 자바 스크립트입니다. this의 제한 사항은 계속 적용됩니다.

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

그러나 당신은 (심지어 자바 스크립트) 프로토 타입을 사용한다 : 당신은 분명히 바로 번역을 쓸 수 있습니다. 당신이 그것에 기능을 결합 할 수 => 지방 화살표가 현재 컨텍스트를이다 (그러나 다음 요소 참조 손실)로 :

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

+0

@Naatan : 그렇다고해서 자바 스크립트 버전도 해킹되지 않을까요? 결국, 당신은 객체에 직접 함수를 추가하고 있으며, 클래스 틱 (class-ish)이 없다는 것을 알 수 있습니다. 나는 여기서 싸움을 시작하려하지 않고, 모든 언어에는 꼴 사나운 말도 안되는 작은 모서리가 있으며 보통 그 구석을 다루는 표준 관용구 (또는 10 개)가 있습니다. –

+0

@muistooshort 네 말이 맞아 ..JavaScript는 나에게 나쁜 습관을 가르쳐주었습니다. – Naatan

관련 문제