2011-01-25 13 views
21

Estoy usando miembros de clase para mantener constantes. Ej .:¿Dónde declarar las constantes de clase?

function Foo() { 
} 

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

Esto funciona bien, excepto que parece un poco desorganizado, con todo el código que es específico para Foo por ahí en el ámbito global. Así que pensé en mover la declaración constante dentro de la declaración Foo(), pero ¿no se ejecutaría ese código cada vez que se construye Foo?

Vengo de Java, donde todo está encerrado en un cuerpo de clase, así que estoy pensando que JavaScript podría tener algo similar a eso o algo de trabajo que lo imite.

Respuesta

30

Todo lo que está haciendo en su código es la adición de una propiedad denominada CONSTANT con el valor 1 al objeto de función llamado Foo, a continuación, sobrescribir inmediatamente con el valor 2.

No estoy muy familiarizado con otros idiomas, pero no creo que javascript pueda hacer lo que parece que está intentando.

Ninguna de las propiedades que agregue a Foo se ejecutará. Solo están almacenados en ese espacio de nombres.

¿Quizás quisiste prototipar alguna propiedad en Foo?

function Foo() { 
} 

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

No es lo que buscas sin embargo.

+5

+1 para ponerlo en el prototipo – Jacob

+1

Fijo. Estoy buscando una manera de declarar constantes dentro de un bloque para que A) estén agrupados B) se ejecuten solo una vez. –

+0

¿Ganarle algo al prototipo? – hvgotcodes

2

lo que está haciendo está bien (suponiendo que se da cuenta de que su ejemplo es simplemente establecer la misma propiedad dos veces); es el equivalente de una variable estática en Java (tan cerca como puedas, al menos sin hacer mucho trabajo). Además, no es del todo global, ya que está en la función de constructor, es espacio de nombres eficaz para su 'clase'.

1

Sus constantes son solo variables, y no sabrá si las intenta sobreescribir inadvertidamente. También tenga en cuenta que a Javascript le falta la noción de "clase".

Sugiero que cree funciones que devuelvan valores que necesita constantes.

Para obtener el gusto de Javascript, encuentre Javascript: the Good Parts y aprenda las formas idiomáticas. Javascript es muy diferente de Java.

3

si las constantes son para ser utilizados en el interior del objeto solamente:

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

Si no es así, hacerlo de esta manera:

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

Es mucho más fácil de leer y más fácil de averiguar lo que el la función lo hace.

3

Si está utilizando jQuery, puede usar la función $ .extend para categorizar todo.

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

también con espacios de nombres

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

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

¿No significa eso que tiene que escribir Constants.Const1.CONSTANT1 para acceder a él? –

+0

correcto, ese es el punto, use esto solo si desea tener todas sus constantes agrupadas en un espacio de nombres, lo cual es útil cuando tiene muchas funciones Const y le gusta mantenerlas organizadas. –

14

Usted debe hacer sus constantes como usted ha dicho:

function Foo() { 
} 

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

Y acceder así:

Foo.CONSTANT1; 

o

anInstanceOfFoo.__proto__.constructor.CONSTANT1; 

Todas las demás soluciones asignan otra parte de la memoria cuando crea otro objeto, por lo que no es una constante. No debe hacer lo siguiente:

Foo.prototype.CONSTANT1 = 1; 
+0

Tenga en cuenta que __proto__ no siempre está disponible. Además, __proto __. Constructor no es siempre lo que crees que es, especialmente. en caso de múltiples niveles de herencia, si el autor de la clase no tuvo especial cuidado en configurarlo. Simplemente puede usar unInstanceOfFoo.CONSTANT1, y se resolverá muy bien debido a la protocadena. –

+0

Los combino ocasionalmente: 'Foo.value = Foo.prototype.value = 42;' – superlukas

0

Usted dijo que su procedentes de Java - ¿Por qué no almacenar esa clase en 1 archivo a continuación, y las constantes al final del archivo. Esto es lo que yo uso:

Nombre del archivo: 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() {}; 

Así única diferencia es la posición de cosas estática. No está muy bien alineado dentro de llaves de clase, pero a quién le importa, siempre es Ctrl + clic en IDE (o uso ctr + l para mostrar todos los métodos de clase - IntellijIdea puede hacer eso en JS no sé qué pasa con otros IDE) así que no vas a buscarla por su ojo;)

sí y yo utilizo _ antes método estático - no se necesita, no sé por qué empecé a hacer eso :)

2

en primer lugar, recomiendo mover la declaración de la clase dentro de un IIFE. Esto limpia el código, lo que lo hace más autónomo, y le permite usar variables locales sin contaminar el espacio de nombres global. Su código se convierte en:

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

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

    return Foo; 
})(); 

El problema con la asignación de las constantes directamente a la clase como atributos es que esas son grabable. Ver este fragmento:

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 mejor solución que he encontrado es para definir las propiedades de sólo lectura para acceder a las constantes fuera de la clase.

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>

(Técnicamente se podría deshacerse de la declaración const CONSTANT1 y simplemente devolver el valor de la definición de la propiedad, pero prefiero esto porque hace que sea más fácil de ver todas las constantes de un vistazo.)

Cuestiones relacionadas