2012-04-12 15 views
10

Ich lerne CoffeeScript, und ich habe ein paar kleine Kopfschmerzen, die ich nicht ganz in der Lage war, herauszufinden. Wenn ich ein Objekt erzeuge, um bestimmte Dinge zu tun, brauche ich gelegentlich eine Instanzvariable für dieses Objekt, das zwischen Methoden geteilt wird. Zum Beispiel, würde Ich mag, dies zu tun:CoffeeScript Instanzvariable

testObject = 

    var message # <- Doesn't work in CoffeeScript. 

    methodOne: -> 
    message = "Foo!" 

    methodTwo: -> 
    alert message 

jedoch nicht var in Coffeescript verwenden können, und ohne diese Erklärung message ist nur sichtbar innerhalb methodOne. Also, wie erstellt man eine Instanzvariable in einem Objekt in CoffeeScript?


Update: Festtippfehler in meinem Beispiel so die Methoden tatsächlich Methoden sind :)

+0

BTW bewusst, dass ich bin, dass ich 'Nachricht tun konnte =" "', aber ich will wirklich nur, dass die Variable null ist, also kann ich das Verhalten basierend auf der Existenz statt einer komplexeren Prüfung setzen, um zu sehen, ob es nicht "leer" ist. – Andrew

+0

Sie können auch "message = null" einstellen willst du nicht? – Sandro

+0

Wenn ich 'message = null 'versuche, bekomme ich' ParseError Unexpected' TERMINATOR'' – Andrew

Antwort

12

Das kann Ihnen nicht gefallen. Um es mit dem language reference:

Weil Sie keinen direkten Zugriff auf das Schlüsselwort var haben, ist es unmöglich, eine äußere Variable absichtlich beschatten, können Sie nur darauf verweisen. Achten Sie also darauf, dass Sie den Namen einer externen Variablen nicht versehentlich wiederverwenden, wenn Sie eine tief verschachtelte Funktion schreiben.

aber was Sie versuchen, entweder nicht zu tun möglich sein, in JS, wäre es zu

testObject = { 
    var message; 
    methodOne: message = "Foo!", 
    methodTwo: alert(message) 
} 

gleichwertig sein, die nicht gültig JS ist, da Sie nicht eine Variable deklarieren können in einem Objekt wie diesem; Sie müssen Funktionen verwenden, um Methoden zu definieren. Zum Beispiel in Coffeescript:

testObject = 
    message: '' 
    methodOne: -> 
     this.message = "Foo!" 
    methodTwo: -> 
     alert message 

Sie können auch @ als Abkürzung für ‚das.‘ Verwenden, das heißt @message statt this.message.

betrachten Alternativ mit Coffee der class syntax:

class testObject 
    constructor: -> 
     @message = '' 

    methodOne: -> 
     @message = "Foo!" 

    methodTwo: -> 
     alert @message 
+0

Tolles Beispiel, danke! – Andrew

1

Sie können die Eigenschaft definieren mit:

message: null 

Aber, Sie sind zur Zeit nicht Definieren von Methoden - Sie brauchen -> dafür.

Um Präfixeigenschaften innerhalb der Methoden zu referenzieren, geben Sie den Eigenschaftsnamen @ voran.

testObject = 

    message: null 

    methodOne: -> 
    @message = "Foo!" 

    methodTwo: -> 
    alert @message 
+0

' -> 'ist nicht erforderlich: siehe [meine Version] (http://coffeescript.org/#try:testObject%20%3D%20%0A%0A%20%20methodOne%3A%0A%20% 20% 20% 20% 40Message% 20% 3D% 20% 22Foo!% 22% 0A% 0A% 20% 20MethodTwo% 3A% 0A% 20% 20% 20% 20alert% 20% 40Message) –

+0

@KristallofferSHansen Ihre Version isn ' t repariert; Wie Sie sehen, wenn Sie auf dieser Seite auf "Ausführen" klicken, wird sofort ein Alarmdialog angezeigt, und das ist wahrscheinlich nicht der Fall, hinter dem Andrew her ist. Wahrscheinlich möchte er die Ausführung verzögern, bis diese Methode aufgerufen wird. – Lauren

+0

@KristofferSHansen Es ist für Funktion/Methoden. Ohne es wird "methodTwo" auf das Ergebnis des Aufrufs von "alert" gesetzt, nicht eine Funktion, die wiederum "alert" aufruft. –

5

nur darauf hinweisen zu @ Lauren Antwort hinzufügen, was wollten Sie ist im Grunde die module pattern :

Dabei ist message eine "private" Variable, die nur diesen Methoden zur Verfügung steht.

Je nach Kontext kann man auch Nachricht, bevor das Objekt deklarieren, so dass es für beide Methoden verfügbar ist (wenn in diesem Zusammenhang ausgeführt):

message = null 

testObject = 
    methodOne: -> message = "Foo!" 
    methodTwo: -> alert message 
+0

Danke für die zusätzlichen Informationen, das ist hilfreich! – Andrew

+0

Korrekt, aber Ihr Code ist ein bisschen buggy: 'do' wird einfach eine Schließung erstellen, Sie können daher keine Eigenschaften definieren, sondern stattdessen vars verwenden (' methodOne = -> ... 'etc.) Auch sollte die return-Anweisung wahrscheinlich be '{methodOne: methodOne, MethodeTwo: methodTwo}'. Natürlich könnten Sie Ihre Methodendefinitionen stattdessen direkt in die return-Anweisung einfügen ... –

+1

@JulianD. * Copy & Pasta * :) Die Return-Anweisung verwendet [Destrukturierungsauftrag] (http://coffeescript.org/#destrukturing). –