¿Hay alguna manera de usar constantes en JavaScript ?
Si no, ¿cuál es la práctica común para especificar variables que se usan como constantes?
fuente
¿Hay alguna manera de usar constantes en JavaScript ?
Si no, ¿cuál es la práctica común para especificar variables que se usan como constantes?
Desde ES2015 , JavaScript tiene una noción de const
:
const MY_CONSTANT = "some-value";
Esto funcionará en casi todos los navegadores, excepto IE 8, 9 y 10 . Algunos también pueden necesitar el modo estricto habilitado.
Puede usar var
convenciones como ALL_CAPS para mostrar que ciertos valores no deben modificarse si necesita admitir navegadores más antiguos o si está trabajando con código heredado:
var MY_CONSTANT = "some-value";
const
palabra clave. Actualmente es compatible con todos los navegadores modernos, excepto IE.
Object.defineProperty
para crear propiedades de solo lectura que tampoco se pueden eliminar. Esto funciona en la versión actual de todos los principales navegadores (pero incorrectamente en IE8 ). Ver la respuesta de @NotAName
const
palabra clave ahora es oficialmente parte del idioma y es compatible con todos los navegadores. De acuerdo con statcounter.com, solo un pequeño porcentaje de usuarios de Internet todavía usa versiones antiguas del navegador que no son compatibles const
.
¿Estás tratando de proteger las variables contra modificaciones? Si es así, puede usar un patrón de módulo:
var CONFIG = (function() {
var private = {
'MY_CONST': '1',
'ANOTHER_CONST': '2'
};
return {
get: function(name) { return private[name]; }
};
})();
alert('MY_CONST: ' + CONFIG.get('MY_CONST')); // 1
CONFIG.MY_CONST = '2';
alert('MY_CONST: ' + CONFIG.get('MY_CONST')); // 1
CONFIG.private.MY_CONST = '2'; // error
alert('MY_CONST: ' + CONFIG.get('MY_CONST')); // 1
Con este enfoque, los valores no pueden modificarse. Pero, debe usar el método get () en CONFIG :(.
Si no necesita proteger estrictamente el valor de las variables, simplemente haga lo sugerido y use una convención de ALL CAPS.
CONFIG.get = someNewFunctionThatBreaksTheCode
... En general, absolutamente no puede aplicar constantes en JS (sin palabra clave const). Casi lo único que puede hacer es limitar la visibilidad.
private
es una palabra reservada para el futuro en JavaScript, no la usaría si fuera usted.
La const
palabra clave se encuentra en el borrador de ECMAScript 6, pero hasta ahora solo cuenta con una pequeña cantidad de compatibilidad con el navegador: http://kangax.github.io/compat-table/es6/ . La sintaxis es:
const CONSTANT_NAME = 0;
const
, no arroja ningún error. La asignación simplemente falla y la constante todavía tiene su valor original. Este es un defecto de diseño importante en mi humilde opinión, pero siempre que haya una convención de nomenclatura clara y coherente (como la popular ALL_CAPS), no creo que cause demasiado dolor.
'use strict'
.
ALL CAPS
?
"use strict";
var constants = Object.freeze({
"π": 3.141592653589793 ,
"e": 2.718281828459045 ,
"i": Math.sqrt(-1)
});
constants.π; // -> 3.141592653589793
constants.π = 3; // -> TypeError: Cannot assign to read only property 'π' …
constants.π; // -> 3.141592653589793
delete constants.π; // -> TypeError: Unable to delete property.
constants.π; // -> 3.141592653589793
Ver Object.freeze . Puede usarloconst
si desea que la constants
referencia también sea de solo lectura.
i
const
declaración ES6 , por ejemplo, las propiedades no se pueden volver a declarar o reasignar, pero si son de tipo de datos object
, se pueden mutar.
const constants
lugar de var constants
evitar que la variable se reasigne.
IE admite constantes, más o menos, por ejemplo:
<script language="VBScript">
Const IE_CONST = True
</script>
<script type="text/javascript">
if (typeof TEST_CONST == 'undefined') {
const IE_CONST = false;
}
alert(IE_CONST);
</script>
const
). ¿Puedes explicar qué le pasa?
ECMAScript 5 introduce Object.defineProperty
:
Object.defineProperty (window,'CONSTANT',{ value : 5, writable: false });
Es compatible con todos los navegadores modernos (así como IE ≥ 9).
Ver también: Object.defineProperty en ES5?
writable: false
será en realidad un error si el código que hace la tarea está siendo interpretado en modo estricto de ECMAScript 5. Solo otra razón para escribir 'use strict'
en su código.
No, no en general. Firefox implementa const
pero sé que IE no.
@John señala una práctica de nomenclatura común para concursos que se ha utilizado durante años en otros idiomas, no veo ninguna razón por la que no pueda usar eso. Por supuesto, eso no significa que alguien no escribirá sobre el valor de la variable de todos modos. :)
En JavaScript, mi preferencia es usar funciones para devolver valores constantes.
function MY_CONSTANT() {
return "some-value";
}
alert(MY_CONSTANT());
Los documentos web de Mozillas MDN contienen buenos ejemplos y explicaciones sobre const
. Extracto:
// define MY_FAV as a constant and give it the value 7
const MY_FAV = 7;
// this will throw an error - Uncaught TypeError: Assignment to constant variable.
MY_FAV = 20;
Pero es triste que IE9 / 10 todavía no sea compatible const
. Y la razón es absurda :
Entonces, ¿qué está haciendo IE9 con const? Hasta ahora, nuestra decisión ha sido no apoyarlo. Todavía no es una función de consenso, ya que nunca ha estado disponible en todos los navegadores.
...
Al final, parece que la mejor solución a largo plazo para la web es dejarla de lado y esperar a que los procesos de estandarización sigan su curso.
¿No lo implementan porque otros navegadores no lo implementaron correctamente? ¿Demasiado miedo de hacerlo mejor? Definiciones de estándares o no, una constante es una constante: establece una vez, nunca cambia.
Y a todas las ideas: cada función se puede sobrescribir (XSS, etc.). Entonces no hay diferencia en var
o function(){return}
. const
Es la única constante real.
Actualización: IE11 admite const
:
EI11 incluye soporte para las características bien definidas y de uso general de la norma ECMAScript 6 emergentes incluyendo let,
const
,Map
,Set
, yWeakMap
, así como__proto__
para la interoperabilidad mejorada.
Si no te importa usar funciones:
var constant = function(val) {
return function() {
return val;
}
}
Este enfoque le brinda funciones en lugar de variables regulares, pero garantiza * que nadie puede alterar el valor una vez que se establece.
a = constant(10);
a(); // 10
b = constant(20);
b(); // 20
Personalmente, esto me parece bastante agradable, especialmente después de haberme acostumbrado a este patrón de observables noqueados.
* A menos que alguien redefina la función constant
antes de que la llame
a = constant(10); a(10); // 10
seguido de a = constant(25); a(); //25
, no hay errores o advertencias, no hay indicios de que su constante se haya roto.
a
entonces cambiará a un nuevo valor
con la "nueva" Object api puedes hacer algo como esto:
var obj = {};
Object.defineProperty(obj, 'CONSTANT', {
configurable: false
enumerable: true,
writable: false,
value: "your constant value"
});
Eche un vistazo a esto en el MDN de Mozilla para obtener más detalles. No es una variable de primer nivel, ya que está adjunta a un objeto, pero si tiene un alcance, cualquier cosa, puede adjuntarlo a eso. this
debería funcionar también. Entonces, por ejemplo, hacer esto en el ámbito global declarará un valor pseudo constante en la ventana (lo cual es una muy mala idea, no debe declarar descuidadamente los valores globales)
Object.defineProperty(this, 'constant', {
enumerable: true,
writable: false,
value: 7,
configurable: false
});
> constant
=> 7
> constant = 5
=> 7
nota: la asignación le devolverá el valor asignado en la consola, pero el valor de la variable no cambiará
Agrupe las constantes en estructuras donde sea posible:
Ejemplo, en mi proyecto de juego actual, he usado a continuación:
var CONST_WILD_TYPES = {
REGULAR: 'REGULAR',
EXPANDING: 'EXPANDING',
STICKY: 'STICKY',
SHIFTING: 'SHIFTING'
};
Asignación:
var wildType = CONST_WILD_TYPES.REGULAR;
Comparacion:
if (wildType === CONST_WILD_TYPES.REGULAR) {
// do something here
}
Más recientemente estoy usando, para comparar:
switch (wildType) {
case CONST_WILD_TYPES.REGULAR:
// do something here
break;
case CONST_WILD_TYPES.EXPANDING:
// do something here
break;
}
IE11 es con el nuevo estándar ES6 que tiene una declaración 'const'.
Lo anterior funciona en navegadores anteriores como IE8, IE9 e IE10.
Puede equipar fácilmente su script con un mecanismo para constantes que se puede establecer pero no alterar. Un intento de alterarlos generará un error.
/* author Keith Evetts 2009 License: LGPL
anonymous function sets up:
global function SETCONST (String name, mixed value)
global function CONST (String name)
constants once set may not be altered - console error is generated
they are retrieved as CONST(name)
the object holding the constants is private and cannot be accessed from the outer script directly, only through the setter and getter provided
*/
(function(){
var constants = {};
self.SETCONST = function(name,value) {
if (typeof name !== 'string') { throw new Error('constant name is not a string'); }
if (!value) { throw new Error(' no value supplied for constant ' + name); }
else if ((name in constants) ) { throw new Error('constant ' + name + ' is already defined'); }
else {
constants[name] = value;
return true;
}
};
self.CONST = function(name) {
if (typeof name !== 'string') { throw new Error('constant name is not a string'); }
if ( name in constants ) { return constants[name]; }
else { throw new Error('constant ' + name + ' has not been defined'); }
};
}())
// ------------- demo ----------------------------
SETCONST( 'VAT', 0.175 );
alert( CONST('VAT') );
//try to alter the value of VAT
try{
SETCONST( 'VAT', 0.22 );
} catch ( exc ) {
alert (exc.message);
}
//check old value of VAT remains
alert( CONST('VAT') );
// try to get at constants object directly
constants['DODO'] = "dead bird"; // error
Olvídate de IE y usa la const
palabra clave.
Sin embargo, no existe una forma predefinida exacta de navegador cruzado para hacerlo, puede lograrlo controlando el alcance de las variables como se muestra en otras respuestas.
Pero sugeriré usar el espacio de nombre para distinguirlo de otras variables. Esto reducirá la posibilidad de colisión al mínimo de otras variables.
Espacio de nombres adecuado como
var iw_constant={
name:'sudhanshu',
age:'23'
//all varibale come like this
}
así que mientras se usa será iw_constant.name
oiw_constant.age
También puede bloquear agregar cualquier clave nueva o cambiar cualquier clave dentro de iw_constant utilizando el método Object.freeze. Sin embargo, no es compatible con el navegador heredado.
ex:
Object.freeze(iw_constant);
Para navegadores más antiguos, puede usar polyfill para el método de congelación.
Si está de acuerdo con la siguiente función de llamada, es la mejor forma de navegador cruzado para definir constante. Alcanzar su objeto dentro de una función de ejecución automática y devolver una función get para sus constantes, por ejemplo:
var iw_constant= (function(){
var allConstant={
name:'sudhanshu',
age:'23'
//all varibale come like this
};
return function(key){
allConstant[key];
}
};
// para obtener el valor use
iw_constant('name')
oiw_constant('age')
** En ambos ejemplos, debe tener mucho cuidado con el espaciado de nombres para que su objeto o función no se reemplace a través de otra biblioteca.
Por un tiempo, especifiqué "constantes" (que todavía no eran realmente constantes) en literales de objetos pasados a las with()
declaraciones. Pensé que era muy inteligente. Aquí hay un ejemplo:
with ({
MY_CONST : 'some really important value'
}) {
alert(MY_CONST);
}
En el pasado, también he creado un CONST
espacio de nombres donde pondría todas mis constantes. De nuevo, con los gastos generales. Sheesh
Ahora, solo lo hago var MY_CONST = 'whatever';
a KISS .
with
.
Mi opinión (solo funciona con objetos).
var constants = (function(){
var a = 9;
//GLOBAL CONSTANT (through "return")
window.__defineGetter__("GCONST", function(){
return a;
});
//LOCAL CONSTANT
return {
get CONST(){
return a;
}
}
})();
constants.CONST = 8; //9
alert(constants.CONST); //9
¡Tratar! Pero entienda: este es un objeto, pero no una variable simple.
Prueba también solo:
const a = 9;
Yo también he tenido un problema con esto. Y después de bastante tiempo buscando la respuesta y observando todas las respuestas de todos, creo que he encontrado una solución viable para esto.
Parece que la mayoría de las respuestas que he encontrado es usar funciones para mantener las constantes. Como comentan muchos de los usuarios de MUCHOS foros, los usuarios pueden sobrescribir fácilmente las funciones del lado del cliente. La respuesta de Keith Evetts me intrigó de que el exterior no puede acceder al objeto de constantes, sino solo desde las funciones del interior.
Entonces se me ocurrió esta solución:
Ponga todo dentro de una función anónima para que las variables, objetos, etc. no puedan ser cambiados por el lado del cliente. También oculte las funciones 'reales' haciendo que otras funciones llamen a las funciones 'reales' desde adentro. También pensé en usar funciones para verificar si un usuario ha cambiado una función en el lado del cliente. Si se han cambiado las funciones, cámbielas nuevamente usando variables que estén 'protegidas' en el interior y que no se puedan cambiar.
/*Tested in: IE 9.0.8; Firefox 14.0.1; Chrome 20.0.1180.60 m; Not Tested in Safari*/
(function(){
/*The two functions _define and _access are from Keith Evetts 2009 License: LGPL (SETCONST and CONST).
They're the same just as he did them, the only things I changed are the variable names and the text
of the error messages.
*/
//object literal to hold the constants
var j = {};
/*Global function _define(String h, mixed m). I named it define to mimic the way PHP 'defines' constants.
The argument 'h' is the name of the const and has to be a string, 'm' is the value of the const and has
to exist. If there is already a property with the same name in the object holder, then we throw an error.
If not, we add the property and set the value to it. This is a 'hidden' function and the user doesn't
see any of your coding call this function. You call the _makeDef() in your code and that function calls
this function. - You can change the error messages to whatever you want them to say.
*/
self._define = function(h,m) {
if (typeof h !== 'string') { throw new Error('I don\'t know what to do.'); }
if (!m) { throw new Error('I don\'t know what to do.'); }
else if ((h in j) ) { throw new Error('We have a problem!'); }
else {
j[h] = m;
return true;
}
};
/*Global function _makeDef(String t, mixed y). I named it makeDef because we 'make the define' with this
function. The argument 't' is the name of the const and doesn't need to be all caps because I set it
to upper case within the function, 'y' is the value of the value of the const and has to exist. I
make different variables to make it harder for a user to figure out whats going on. We then call the
_define function with the two new variables. You call this function in your code to set the constant.
You can change the error message to whatever you want it to say.
*/
self._makeDef = function(t, y) {
if(!y) { throw new Error('I don\'t know what to do.'); return false; }
q = t.toUpperCase();
w = y;
_define(q, w);
};
/*Global function _getDef(String s). I named it getDef because we 'get the define' with this function. The
argument 's' is the name of the const and doesn't need to be all capse because I set it to upper case
within the function. I make a different variable to make it harder for a user to figure out whats going
on. The function returns the _access function call. I pass the new variable and the original string
along to the _access function. I do this because if a user is trying to get the value of something, if
there is an error the argument doesn't get displayed with upper case in the error message. You call this
function in your code to get the constant.
*/
self._getDef = function(s) {
z = s.toUpperCase();
return _access(z, s);
};
/*Global function _access(String g, String f). I named it access because we 'access' the constant through
this function. The argument 'g' is the name of the const and its all upper case, 'f' is also the name
of the const, but its the original string that was passed to the _getDef() function. If there is an
error, the original string, 'f', is displayed. This makes it harder for a user to figure out how the
constants are being stored. If there is a property with the same name in the object holder, we return
the constant value. If not, we check if the 'f' variable exists, if not, set it to the value of 'g' and
throw an error. This is a 'hidden' function and the user doesn't see any of your coding call this
function. You call the _getDef() function in your code and that function calls this function.
You can change the error messages to whatever you want them to say.
*/
self._access = function(g, f) {
if (typeof g !== 'string') { throw new Error('I don\'t know what to do.'); }
if ( g in j ) { return j[g]; }
else { if(!f) { f = g; } throw new Error('I don\'t know what to do. I have no idea what \''+f+'\' is.'); }
};
/*The four variables below are private and cannot be accessed from the outside script except for the
functions inside this anonymous function. These variables are strings of the four above functions and
will be used by the all-dreaded eval() function to set them back to their original if any of them should
be changed by a user trying to hack your code.
*/
var _define_func_string = "function(h,m) {"+" if (typeof h !== 'string') { throw new Error('I don\\'t know what to do.'); }"+" if (!m) { throw new Error('I don\\'t know what to do.'); }"+" else if ((h in j) ) { throw new Error('We have a problem!'); }"+" else {"+" j[h] = m;"+" return true;"+" }"+" }";
var _makeDef_func_string = "function(t, y) {"+" if(!y) { throw new Error('I don\\'t know what to do.'); return false; }"+" q = t.toUpperCase();"+" w = y;"+" _define(q, w);"+" }";
var _getDef_func_string = "function(s) {"+" z = s.toUpperCase();"+" return _access(z, s);"+" }";
var _access_func_string = "function(g, f) {"+" if (typeof g !== 'string') { throw new Error('I don\\'t know what to do.'); }"+" if ( g in j ) { return j[g]; }"+" else { if(!f) { f = g; } throw new Error('I don\\'t know what to do. I have no idea what \\''+f+'\\' is.'); }"+" }";
/*Global function _doFunctionCheck(String u). I named it doFunctionCheck because we're 'checking the functions'
The argument 'u' is the name of any of the four above function names you want to check. This function will
check if a specific line of code is inside a given function. If it is, then we do nothing, if not, then
we use the eval() function to set the function back to its original coding using the function string
variables above. This function will also throw an error depending upon the doError variable being set to true
This is a 'hidden' function and the user doesn't see any of your coding call this function. You call the
doCodeCheck() function and that function calls this function. - You can change the error messages to
whatever you want them to say.
*/
self._doFunctionCheck = function(u) {
var errMsg = 'We have a BIG problem! You\'ve changed my code.';
var doError = true;
d = u;
switch(d.toLowerCase())
{
case "_getdef":
if(_getDef.toString().indexOf("z = s.toUpperCase();") != -1) { /*do nothing*/ }
else { eval("_getDef = "+_getDef_func_string); if(doError === true) { throw new Error(errMsg); } }
break;
case "_makedef":
if(_makeDef.toString().indexOf("q = t.toUpperCase();") != -1) { /*do nothing*/ }
else { eval("_makeDef = "+_makeDef_func_string); if(doError === true) { throw new Error(errMsg); } }
break;
case "_define":
if(_define.toString().indexOf("else if((h in j) ) {") != -1) { /*do nothing*/ }
else { eval("_define = "+_define_func_string); if(doError === true) { throw new Error(errMsg); } }
break;
case "_access":
if(_access.toString().indexOf("else { if(!f) { f = g; }") != -1) { /*do nothing*/ }
else { eval("_access = "+_access_func_string); if(doError === true) { throw new Error(errMsg); } }
break;
default:
if(doError === true) { throw new Error('I don\'t know what to do.'); }
}
};
/*Global function _doCodeCheck(String v). I named it doCodeCheck because we're 'doing a code check'. The argument
'v' is the name of one of the first four functions in this script that you want to check. I make a different
variable to make it harder for a user to figure out whats going on. You call this function in your code to check
if any of the functions has been changed by the user.
*/
self._doCodeCheck = function(v) {
l = v;
_doFunctionCheck(l);
};
}())
También parece que la seguridad es realmente un problema y no hay forma de "ocultar" su programación desde el lado del cliente. Una buena idea para mí es comprimir su código para que sea realmente difícil para cualquiera, incluido usted, el programador, leerlo y comprenderlo. Hay un sitio al que puede ir: http://javascriptcompressor.com/ . (Este no es mi sitio, no se preocupe, no estoy anunciando). Este es un sitio que le permitirá comprimir y ofuscar el código Javascript de forma gratuita.
Claramente, esto muestra la necesidad de una palabra clave const estandarizada entre navegadores.
Pero por ahora:
var myconst = value;
o
Object['myconst'] = value;
Ambos parecen suficientes y cualquier otra cosa es como disparar una mosca con una bazuca.
Lo uso en const
lugar de var
en mis scripts de Greasemonkey, pero es porque solo se ejecutarán en Firefox ... La
convención de nombres también puede ser el camino a seguir (¡hago ambas cosas!).
En JavaScript, mi práctica ha sido evitar las constantes tanto como puedo y usar cadenas en su lugar. Los problemas con las constantes aparecen cuando desea exponer sus constantes al mundo exterior:
Por ejemplo, uno podría implementar la siguiente API de fecha:
date.add(5, MyModule.Date.DAY).add(12, MyModule.Date.HOUR)
Pero es mucho más corto y más natural simplemente escribir:
date.add(5, "days").add(12, "hours")
De esta manera, los "días" y las "horas" realmente actúan como constantes, porque no puede cambiar desde el exterior cuántos segundos representa "horas". Pero es fácil de sobrescribir MyModule.Date.HOUR
.
Este tipo de enfoque también ayudará en la depuración. Si Firebug te dice action === 18
que es bastante difícil entender lo que significa, pero cuando lo ves action === "save"
, está claro de inmediato.
"Hours"
lugar de hacerlo "hours"
, pero un IDE podría informarle desde el principio que Date.Hours
no está definido.
De acuerdo, esto es feo, pero me da una constante en Firefox y Chromium, una constante inconstante (WTF?) En Safari y Opera, y una variable en IE.
Por supuesto, eval () es malo, pero sin él, IE arroja un error, evitando que se ejecuten los scripts.
Safari y Opera admiten la palabra clave const, pero puede cambiar el valor de const .
En este ejemplo, el código del lado del servidor está escribiendo JavaScript en la página, reemplazando {0} con un valor.
try{
// i can haz const?
eval("const FOO='{0}';");
// for reals?
var original=FOO;
try{
FOO='?NO!';
}catch(err1){
// no err from Firefox/Chrome - fails silently
alert('err1 '+err1);
}
alert('const '+FOO);
if(FOO=='?NO!'){
// changed in Sf/Op - set back to original value
FOO=original;
}
}catch(err2){
// IE fail
alert('err2 '+err2);
// set var (no var keyword - Chrome/Firefox complain about redefining const)
FOO='{0}';
alert('var '+FOO);
}
alert('FOO '+FOO);
¿Para qué es bueno esto? No mucho, ya que no es un navegador cruzado. En el mejor de los casos, quizás tenga un poco de tranquilidad de que al menos algunos navegadores no permitirán que los marcadores o los guiones de terceros modifiquen el valor.
Probado con Firefox 2, 3, 3.6, 4, Iron 8, Chrome 10, 12, Opera 11, Safari 5, IE 6, 9.
Si vale la pena mencionar, puede definir constantes en angular usando$provide.constant()
angularApp.constant('YOUR_CONSTANT', 'value');
Una versión mejorada de la respuesta de Burke que te permite hacer en CONFIG.MY_CONST
lugar de CONFIG.get('MY_CONST')
.
Requiere IE9 + o un navegador web real.
var CONFIG = (function() {
var constants = {
'MY_CONST': 1,
'ANOTHER_CONST': 2
};
var result = {};
for (var n in constants)
if (constants.hasOwnProperty(n))
Object.defineProperty(result, n, { value: constants[n] });
return result;
}());
* Las propiedades son de solo lectura, solo si los valores iniciales son inmutables.
JavaScript ES6 (re) introdujo la const
palabra clave que es compatible con todos los principales navegadores .
Las variables declaradas vía
const
no se pueden volver a declarar o reasignar.
Aparte de eso, se const
comporta de manera similar a let
.
Se comporta como se espera para los tipos de datos primitivos (booleano, nulo, indefinido, número, cadena, símbolo):
const x = 1;
x = 2;
console.log(x); // 1 ...as expected, re-assigning fails
Atención: tenga en cuenta las dificultades con respecto a los objetos:
const o = {x: 1};
o = {x: 2};
console.log(o); // {x: 1} ...as expected, re-assigning fails
o.x = 2;
console.log(o); // {x: 2} !!! const does not make objects immutable!
const a = [];
a = [1];
console.log(a); // 1 ...as expected, re-assigning fails
a.push(1);
console.log(a); // [1] !!! const does not make objects immutable
Si realmente necesita un objeto inmutable y absolutamente constante: solo use const ALL_CAPS
para aclarar su intención. De todos const
modos, es una buena convención para todas las declaraciones, así que confíe en ella.
Otra alternativa es algo como:
var constants = {
MY_CONSTANT : "myconstant",
SOMETHING_ELSE : 123
}
, constantMap = new function ConstantMap() {};
for(var c in constants) {
!function(cKey) {
Object.defineProperty(constantMap, cKey, {
enumerable : true,
get : function(name) { return constants[cKey]; }
})
}(c);
}
Entonces simplemente: var foo = constantMap.MY_CONSTANT
Si constantMap.MY_CONSTANT = "bar"
lo hiciera, no tendría ningún efecto, ya que estamos tratando de usar un operador de asignación con un captador, por constantMap.MY_CONSTANT === "myconstant"
lo tanto, seguiría siendo cierto.
en Javascript ya existen constantes . Define una constante como esta:
const name1 = value;
Esto no puede cambiar mediante la reasignación.
La palabra clave 'const' se propuso anteriormente y ahora se ha incluido oficialmente en ES6. Al usar la palabra clave const, puede pasar un valor / cadena que actuará como una cadena inmutable.
Introducir constantes en JavaScript es, en el mejor de los casos, un truco.
Una buena manera de hacer valores persistentes y accesibles globalmente en JavaScript sería declarar un objeto literal con algunas propiedades de "solo lectura" como esta:
my={get constant1(){return "constant 1"},
get constant2(){return "constant 2"},
get constant3(){return "constant 3"},
get constantN(){return "constant N"}
}
tendrás todas tus constantes agrupadas en un solo objeto accesorio "mi" donde puedes buscar tus valores almacenados o cualquier otra cosa que hayas decidido poner allí para el caso. Ahora probemos si funciona:
my.constant1; >> "constant 1"
my.constant1 = "new constant 1";
my.constant1; >> "constant 1"
Como podemos ver, la propiedad "my.constant1" ha conservado su valor original. Te has hecho algunas buenas constantes temporales 'verdes' ...
Pero, por supuesto, esto solo lo protegerá de modificar, alterar, anular o vaciar accidentalmente el valor constante de su propiedad con un acceso directo como en el ejemplo dado.
De lo contrario, sigo pensando que las constantes son para tontos. Y sigo pensando que intercambiar su gran libertad por un pequeño rincón de seguridad engañosa es el peor intercambio posible.
Rhino.js
implementa const
además de lo mencionado anteriormente.
Chrome
le permite usar la palabra claveconst
para usar constantes. por ejconst ASDF = "asdf"
. Sin embargo, dadoconst
que no es compatible con varios navegadores, generalmente me quedo con unavar
declaración.try{const thing=1091;}catch(e){var thing=1091;}
trabajos.const
ovar
en absoluto?const
tiene el mismo alcance quevar
, y eso es a nivel de función, no a nivel de bloque. Si sigue el próximo estándar ECMAScript,const
tiene el mismo alcance quelet
, lo que significa que no funcionará.