2012-04-12 24 views
10

Sto imparando CoffeeScript e ho un piccolo mal di testa che non sono stato in grado di capire. Se creo un oggetto per fare certe cose, a volte ho bisogno di una variabile di istanza per quell'oggetto da condividere tra i metodi. Per esempio, mi piacerebbe fare questo:Variabile di istanza CoffeeScript

testObject = 

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

    methodOne: -> 
    message = "Foo!" 

    methodTwo: -> 
    alert message 

Tuttavia, non è possibile utilizzare var in CoffeeScript, e senza che la dichiarazione message è visibile solo all'interno methodOne. Quindi, come crei una variabile di istanza in un oggetto in CoffeeScript?


Aggiornamento: errore di battitura fisso nel mio esempio in modo che i metodi sono in realtà metodi :)

+0

BTW mi rendo conto che avrei potuto fare 'message =" "', ma voglio davvero che la variabile sia nullo, così posso impostare il comportamento in base all'esistenza piuttosto che un controllo più complesso per vedere se non è "vuoto" ecc. – Andrew

+0

Puoi anche impostare 'message = null' che è ciò che vuoi no? – Sandro

+0

Quando provo 'message = null' ottengo' ParseError Unexpected 'TERMINATOR'' – Andrew

risposta

12

Non ti piace. Per citare il language reference:

Perché non si dispone di accesso diretto alla parola chiave var, è impossibile ombra una variabile esterna di proposito, si può fare riferimento solo ad esso. Quindi, fai attenzione che non stai riutilizzando accidentalmente il nome di una variabile esterna, se stai scrivendo una funzione profondamente annidata.

Tuttavia quello che stai cercando di fare non sarebbe possibile in JS o, sarebbe equivalente a

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

che non è JS validi, in quanto non è possibile dichiarare una variabile in un oggetto del genere; è necessario utilizzare le funzioni per definire i metodi. Per esempio in CoffeeScript:

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

È inoltre possibile utilizzare @ come una scorciatoia per 'questo.', Vale a dire @message invece di this.message.

alternativa considerare l'utilizzo di CoffeeScript class syntax:

class testObject 
    constructor: -> 
     @message = '' 

    methodOne: -> 
     @message = "Foo!" 

    methodTwo: -> 
     alert @message 
+0

Ottimo esempio, grazie! – Andrew

1

È possibile definire la proprietà con:

message: null 

Ma, non si è attualmente definizione dei metodi: per questo è necessario il ->.

Quindi, per fare riferimento alle proprietà dell'istanza all'interno dei metodi, anteporre i nomi delle proprietà con @.

testObject = 

    message: null 

    methodOne: -> 
    @message = "Foo!" 

    methodTwo: -> 
    alert @message 
+0

' -> 'non è richiesto: vedere [la mia versione fissa] (http://coffeescript.org/#try:testObject%20%3D%20%0A%0A%20%20methodOne%3A%0A%20% 20% 20% 20% 40 messaggio% 20% 3D% 20% 22Foo!% 22% 0A% 0A% 20% 20methodTwo% 3A% 0A% 20% 20% 20% 20alert% 20% 40messaggio) –

+0

@KristofferSHansen la tua versione isn ' t risolto; come puoi vedere premendo 'Esegui' in quella pagina, mostrerebbe immediatamente una finestra di avviso, e probabilmente non è quello che Andrew sta cercando, più probabilmente vorrebbe rinviare la sua esecuzione fino a quando non viene chiamato quel metodo. – Lauren

+0

@KristofferSHansen È per funzione/metodi. Senza di essa, 'methodTwo' è impostato sul risultato di chiamare' alert', non una funzione che a sua volta chiama 'alert'. –

5

solo per aggiungere a @ risposta di Lauren, quello che volevi è fondamentalmente la module pattern :

testObject = do -> 

    message = null 

    methodOne = -> 
    message = "Foo!" 

    methodTwo = -> 
    alert message 

    return { 
    methodOne 
    methodTwo 
    } 

Dove message è una variabile "privata" disponibile solo per questi metodi.

A seconda del contesto si potrebbe anche dichiarare il messaggio prima che l'oggetto in modo che sia a disposizione di entrambi i metodi (se eseguito in questo contesto):

message = null 

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

Grazie per le informazioni extra, questo è utile! – Andrew

+0

Corretto, ma il tuo codice è un po 'buggy: 'do' creerà semplicemente una chiusura, quindi non puoi definire le proprietà, ma dovresti usare invece vars (' methodOne = -> ... 'ecc.) Inoltre, l'istruzione return dovrebbe probabilmente be '{methodOne: methodOne, methodTwo: methodTwo}'. Naturalmente potresti inserire le definizioni dei tuoi metodi direttamente nell'istruzione return ... –

+1

@ JulianD. * copy & pasta * :) L'istruzione return utilizza [assegnamento distruttivo] (http://coffeescript.org/#destructuring). –

Problemi correlati