2011-01-25 29 views
21

Sto usando i membri della classe per contenere le costanti. Es .:Dove dichiarare le costanti di classe?

function Foo() { 
} 

Foo.CONSTANT1 = 1; 
Foo.CONSTANT2 = 2; 

Questo funziona bene, tranne che sembra un po 'disorganizzata, con tutto il codice che è specifico per Foo che in giro in ambito globale. Quindi ho pensato di spostare la dichiarazione costante all'interno della dichiarazione Foo(), ma poi non eseguiresti quel codice ogni volta che viene costruito ?

Vengo da Java, dove tutto è racchiuso in un corpo di classe, quindi sto pensando che JavaScript potrebbe avere qualcosa di simile a quello o un aggeggio che lo imita.

risposta

30

Tutto ciò che si sta facendo nel codice è l'aggiunta di una proprietà denominata CONSTANT con il valore 1 all'oggetto Funzione denominato Foo, quindi sovrascritto immediatamente con il valore 2.

Non ho molta familiarità con altri linguaggi, ma non credo che javascript sia in grado di fare quello che sembra provi.

Nessuna delle proprietà che si sta aggiungendo a Foo verrà mai eseguita. Sono solo memorizzati in quel namespace.

Forse volevi prototipare alcune proprietà su ?

function Foo() { 
} 

Foo.prototype.CONSTANT1 = 1; 
Foo.prototype.CONSTANT2 = 2; 

Non proprio quello che stai cercando però.

+5

+1 per averlo inserito nel prototipo – Jacob

+1

corretto. Sto cercando un modo per dichiarare le costanti all'interno di un blocco in modo che A) siano raggruppate insieme B) vengono eseguite una sola volta. –

+0

lo mette sul prototipo ti guadagna qualcosa? – hvgotcodes

2

quello che stai facendo va bene (supponendo ti rendi conto che il tuo esempio sta semplicemente impostando la stessa proprietà due volte); è l'equivalente di una variabile statica in Java (il più vicino possibile, almeno senza un sacco di lavoro). Inoltre, non è interamente globale, dal momento che è sulla funzione di costruzione, è effettivamente assegnato alla tua "classe".

1

Le tue costanti sono solo variabili e non saprai se provi a sovrascriverle inavvertitamente. Si noti inoltre che Javascript non ha la nozione di "classe".

Suggerisco di creare funzioni che restituiscono valori che è necessario costante.

Per ottenere il gusto di Javascript, trovare Javascript: the Good Parts e imparare i modi idiomatici. Javascript è molto diverso da diverso da Java.

3

SE le costanti devono essere utilizzati all'interno del solo l'oggetto:

function Foo() { 
    var CONSTANT1 = 1,CONSTANT2 = 2; 
} 

In caso contrario, farlo in questo modo:

function Foo(){ 
    this.CONSTANT1=1; 
    this.CONSTANT2=2; 
} 

E 'molto più leggibile e più facile da capire cosa la la funzione fa.

3

Se si utilizza jQuery, è possibile utilizzare la funzione $ .extend per categorizzare tutto.

var MyClass = $.extend(function() { 
     $.extend(this, { 
      parameter: 'param', 
      func: function() { 
       console.log(this.parameter); 
      } 
     }); 
     // some code to do at construction time 
    }, { 
     CONST: 'const' 
    } 
); 
var a = new MyClass(); 
var b = new MyClass(); 
b.parameter = MyClass.CONST; 
a.func();  // console: param 
b.func();  // console: const 
1

anche gli spazi dei nomi

var Constants = { 
    Const1: function() { 
     Const1.prototype.CONSTANT1 = 1; 
     Const1.prototype.CONSTANT2 = 2; 
    }, 

    Const2: function() { 
     Const2.prototype.CONSTANT3 = 4; 
     Const2.prototype.CONSTANT4 = 3; 
    } 
}; 
+1

Non significa che devi scrivere Constants.Const1.CONSTANT1 per accedervi? –

+0

corretto, questo è il punto, usalo solo se desideri raggruppare tutte le tue costanti in uno spazio dei nomi, utile quando hai molte funzioni di Const e ti piace tenerle organizzate. –

14

È necessario rendere i vostri costanti come lei ha detto:

function Foo() { 
} 

Foo.CONSTANT1 = 1; 
Foo.CONSTANT2 = 2; 

e si accede così:

Foo.CONSTANT1; 

o

anInstanceOfFoo.__proto__.constructor.CONSTANT1; 

Tutte le altre soluzioni assegnano un'altra parte della memoria quando si crea un altro oggetto, quindi non è una costante. Non dovresti farlo:

Foo.prototype.CONSTANT1 = 1; 
+0

Nota che __proto__ non è sempre disponibile. Inoltre, il costruttore __proto __. Non è sempre quello che pensi che sia, esp. in caso di più livelli di ereditarietà, se l'autore della classe non ha avuto particolare cura di impostarlo. Puoi semplicemente usare anInstanceOfFoo.CONSTANT1, e si risolverà bene grazie alla proto-catena. –

+0

Li unisco occasionalmente: 'Foo.value = Foo.prototype.value = 42;' – superlukas

0

Lei ha detto vostra venuta da Java - perché non si memorizzano quella classe in 1 file di allora e costanti alla fine del file. Questo è quello che uso:

filename: PopupWindow.js

function PopupWindow() { 
    //private class memebers 
    var popup, lightbox; 
    //public class memeber or method (it is the same in JS if I am right) 
    this.myfuncOrmyMemeber = function() {}; 
} 

//static variable 
PopupWindow._instance = null; 
//same thing again with constant-like name (you can't have "final" in JS if I am right, so it is not immutable constant but its close enough ;) - just remember not to set varibales with BIG_LETTERS :D) 
PopupWindow.MY_CONSTANT = 1; 
//yea, and same thing with static methods again 
PopupWindow._getInstance = function() {}; 

Così unica differenza è la posizione di roba statica. Non è allineato bene all'interno di parentesi graffe di classe, ma a chi importa, è sempre ctrl + clic su IDE (o io uso ctr + l per mostrare tutti i metodi di classe - IntellijIdea può farlo in JS non so come su altri IDE) quindi non lo farai cercare dal tuo occhio;)

Sì e io uso _ prima metodo statico - non è necessario, non so il motivo per cui ho iniziato a fare questo :)

2

In primo luogo, mi consiglia di spostare il dichiarazione di classe all'interno di un IIFE. Questo pulisce il codice, rendendolo più autonomo e consente di utilizzare variabili locali senza inquinare lo spazio dei nomi globale. Il tuo codice diventa:

var Foo = (function() { 
    function Foo() { 
    } 

    Foo.CONSTANT1 = 1; 
    Foo.CONSTANT2 = 2; 

    return Foo; 
})(); 

Il problema con l'assegnazione di costanti direttamente alla classe come attributi è che quelli sono scrivibili. Vedere questo frammento:

var output = document.getElementById("output"); 
 

 
var Foo = (function() { 
 
    function Foo() { 
 
    } 
 

 
    Foo.CONSTANT1 = 1; 
 
    Foo.CONSTANT2 = 2; 
 

 
    return Foo; 
 
})(); 
 

 
Foo.CONSTANT1 = "I'm not very constant"; 
 

 
output.innerHTML = Foo.CONSTANT1;
<div id="output"></div>

La soluzione migliore che ho trovato è quello di definire le proprietà di sola lettura per l'accesso ai costanti al di fuori della classe.

var output = document.getElementById("output"); 
 

 
var Foo = (function() { 
 
    const CONSTANT1 = "I'm very constant"; 
 

 
    function Foo() { 
 
    } 
 

 
    Object.defineProperty(Foo, "CONSTANT1", { 
 
    get: function() { 
 
     return CONSTANT1; 
 
    }, 
 
    }); 
 

 
    return Foo; 
 
})(); 
 

 
Foo.CONSTANT1 = "some other value"; 
 

 
output.innerHTML = Foo.CONSTANT1;
<div id="output"></div>

(Tecnicamente si potrebbe abbandonare la dichiarazione const CONSTANT1 e solo restituire il valore dalla definizione di proprietà, ma preferisco questo perché rende più facile vedere tutte le costanti a colpo d'occhio.)

Problemi correlati