2011-12-02 16 views
11

Sono nuovo a CoffeeScript (e piuttosto inesperto con JS troppo, così dispiace se questo è ingenuo) e stavo cercando di creare una classe, come di seguito:CoffeeScript Classe Membri

class Test 
    a: [] 

    make: -> 
     @a.push ['A', 'B', 'C'] 

    getdata: -> 
     output = "" 
     for i in @a 
      output += i 
     output 

b = new Test 
b.make() 

alert(b.getdata()) 


c = new Test 
c.make() 

alert(c.getdata()) 

L'output che ottengo è: "A, B, C" "A, B, C, A, B, C"

Nonostante crei una nuova istanza di "Test"; la matrice viene aggiunta e non viene cancellata. Cosa sto facendo di sbagliato qui? Sto inizializzando la variabile membro errata?

+3

Si dovrebbe guardare come funziona il prototipo e guardare il codice generato da javascript. Vedo un sacco di questo errore in coffeescript (anche in tutorial/libri di cucina). La regola che uso è definire solo le funzioni e le proprietà statiche nei membri della classe (definisco le proprietà dell'istanza nel costruttore con la sintassi @member). E sì, è un po 'di confusione dato l'uso del coffeescript della parola chiave class. – Guillaume86

+3

nota a margine: 'getdata: -> @ a.join ('')' – tokland

+0

Grazie a Guillaume86 e tokland. Ho imparato molto da questo. – Anoop

risposta

23

Quando si definisce a: [], si sta creando un singolo oggetto matrice sul prototipo di classe. Ogni istanza della classe creata avrà lo stesso oggetto matrice. Ogni volta che un'istanza modifica il valore, la modifica è visibile a tutti gli altri.

Si noti che questo è il caso solo se si modifica , ad esempio aggiungendo elementi a un array. Se si sostituisce il valore, ad esempio assegnando un nuovo array, questo avrà effetto solo sull'istanza corrente.

Quando si desidera una proprietà che è inizializzata su una base per-instance si dovrebbe definire nel constructor, quando l'istanza è effettivamente creato:

class Test 
    constructor: -> 
     @a = [] 
     @a.push ['A', 'B', 'C'] 

    getdata: -> 
     output = "" 
     for i in @a 
      output += i 
     output 

b = new Test 

alert(b.getdata()) 


c = new Test 

alert(c.getdata()) 

Try this out e vi accorgerete che funziona come tu vuoi.

+1

Non c'è da meravigliarsi se le persone si confondono quando vedi cose del genere: http://coffeescriptcookbook.com/chapters/classes_and_objects/chaining – Guillaume86

+0

Grazie! Ora capisco. Ciò che mi aveva confuso ancora di più era la modifica/sostituzione della differenza di comportamento. Ora anche questo è cancellato. Grazie per l'aiuto. – Anoop

+0

Questo cattivo consiglio si ripete anche qui http://arcturo.github.io/library/coffeescript/03_classes.html e sono quasi caduto nella stessa trappola. Vorrei che i documenti di Coffeescript consiglierebbero su questo. – aaron