Const en JavaScript: ¿cuándo usarlo y es necesario?

349

Recientemente me encontré con la constpalabra clave en JavaScript. Por lo que puedo decir, se usa para crear variables inmutables , y lo he probado para asegurarme de que no se pueda redefinir (en Node.js):

const x = 'const';
const x = 'not-const';

// Will give an error: 'constant 'x' has already been defined'

Me doy cuenta de que aún no está estandarizado en todos los navegadores, pero solo estoy interesado en el contexto de Node.js V8 , y he notado que ciertos desarrolladores / proyectos parecen favorecerlo mucho cuando la varpalabra clave podría usarse para mismo efecto

Entonces mis preguntas son:

  • ¿Cuándo es apropiado usar consten lugar de var?
  • ¿Debería usarse cada vez que se declara una variable que no se va a reasignar?
  • ¿Realmente hace alguna diferencia si varse usa en lugar de consto viceversa?
axdg
fuente
1
Eso todavía no parece estar estandarizado (¿tal vez en EC6?). Encontrará información adicional al respecto aquí: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Sebastien C.
1
Const tiene un mal desempeño, aunque jsperf.com/const-vs-var-mod-3
Deepu

Respuestas:

462

Hay dos aspectos en sus preguntas: cuáles son los aspectos técnicos del uso en constlugar de vary cuáles son los aspectos relacionados con el ser humano al hacerlo.

La diferencia técnica es significativa. En lenguajes compilados, una constante será reemplazada en tiempo de compilación y su uso permitirá otras optimizaciones como la eliminación de código muerto para aumentar aún más la eficiencia del código en tiempo de ejecución. Los motores JavaScript recientes (término poco utilizado) realmente compilan el código JS para obtener un mejor rendimiento, por lo que el uso de la palabra clave const les informaría que las optimizaciones descritas anteriormente son posibles y deben hacerse. Esto da como resultado un mejor rendimiento.

El aspecto humano está relacionado con la semántica de la palabra clave. Una variable es una estructura de datos que contiene información que se espera que cambie. Una constante es una estructura de datos que contiene información que nunca cambiará. Si hay margen de error, varsiempre se debe utilizar. Sin embargo, no toda la información que nunca cambia durante la vida útil de un programa debe declararse con const. Si en diferentes circunstancias la información cambia, úsela varpara indicar que, incluso si el cambio real no aparece en su código.

Tibos
fuente
44
Saludos, supuse que Mozilla / Google no habría agregado soporte constante a los motores JS sin ninguna razón. Me aseguraré de usar const donde corresponda.
axdg
66
constlos objetos parecen ser mutables, así que no estoy seguro de cuán estricto es realmente el compilador JS. Quizás el modo "usar estricto" también marque la diferencia.
Rudie
99
@Rudie La característica que está buscando se llama congelar el objeto. constsimplemente evita reasignar la "variable" a otro valor. const a = {}; a = {};arrojará un error en modo estricto.
Tibos
Uso const en general en lugar de permitir la mayoría de las variables, al igual que en Java agrego final a la mayoría de las declaraciones de variables.
codificación
2
If there is room for error, var should always be used. Hoy esto ya no se aplica, con herramientas como ESLint que apuntan a la constviolación de inmediato.
vitaly-t
72

Actualización 2017

Esta respuesta todavía recibe mucha atención. Vale la pena señalar que esta respuesta se publicó a principios de 2014 y mucho ha cambiado desde entonces.El apoyo es ahora la norma. Todos los navegadores modernos ahora son compatibles, constpor lo que debería ser bastante seguro de usar sin ningún problema.


Respuesta original de 2014

A pesar de tener un soporte de navegador bastante decente , evitaría usarlo por ahora. Del artículo de MDN sobreconst :

La implementación actual de const es una extensión específica de Mozilla y no forma parte de ECMAScript 5. Es compatible con Firefox y Chrome (V8). A partir de Safari 5.1.7 y Opera 12.00, si define una variable con const en estos navegadores, aún puede cambiar su valor más adelante. No se admite en Internet Explorer 6-10, pero se incluye en Internet Explorer 11. La palabra clave const actualmente declara la constante en el alcance de la función (como las variables declaradas con var).

Luego continúa diciendo:

constserá definido por ECMAScript 6, pero con semántica diferente. De manera similar a las variables declaradas con la declaración let, las constantes declaradas con const tendrán un alcance de bloque.

Si lo usa const, tendrá que agregar una solución alternativa para admitir navegadores ligeramente más antiguos.

James Donnelly
fuente
66
Gran respuesta, aunque ya leí el artículo sobre MDN. Como dije, estaba más interesado en saber si V8 trataría específicamente const de manera diferente a var. Creo que @Tibos lo aclaró.
axdg
James gracias por señalar el aspecto de soporte. En mi opinión, todas las respuestas de JavaScript deben incluir un desglose de soporte del navegador. muy bien explicado
hubson bropa
44
Note ES6 recibió una congelación de funciones en agosto de 2014. En julio de 2015, el estándar se lanzó oficialmente. Si está leyendo esto ahora, significa que debe seguir la respuesta aceptada tal como se describe si su código está administrado por un motor actualizado.
Filip Dupanović
La pregunta de OP es específica de node.js
Nicu Surdu
@NicolaeSurdu seguro. También es de enero de 2014, por lo que probablemente sea más redundante ahora en 2017.
James Donnelly
41

Para constsaber por qué usar , la respuesta de @ Tibos es excelente.

Pero tu dijiste:

Por lo que puedo decir, se usa para crear variables inmutables

Eso esta mal . La mutación de una variable es diferente de la reasignación:

var hello = 'world' // assigning
hello = 'bonjour!' // reassigning

Con const, no puedes hacer eso:

const hello = 'world'
hello = 'bonjour!' // error

Pero puedes mutar tu variable:

const marks = [92, 83]
marks.push(95)
console.log(marks) // [92, 83, 95] -> the variable has been mutated.

Entonces, cualquier proceso que cambie el valor de la variable sin usar el =signo está mutando la variable.

Nota: +=por ejemplo es ... reasignar!

var a = 5
a += 2 // is the same as a = a + 2

Entonces, la conclusión es: constno le impide mutar variables, le impide reasignarlas .

matemáticas2001
fuente
44
su afirmación "cualquier proceso que cambie el valor de la variable sin usar el =signo está silenciando" es técnicamente incorrecto. Por ejemplo, const marks=[92,83]; marks[2]=95; console.log(marks)saldrá [92, 83, 95]. marksha sido mutado, a través del signo igual.
chharvey
55
"Pero usted dijo: << Por lo que puedo decir, se usa para crear variables inmutables >> Eso está mal . La mutación de una variable es diferente de la reasignación" No, no lo es. Reasignar es mutar la variable. Estás hablando de mutar el objeto al que se refiere la referencia en la variable. Eso es algo completamente diferente.
TJ Crowder
Llegué aquí porque estoy tratando de entender consten el contexto de las matrices (similar al ejemplo que utilizó @chharvey). En el caso de const countArray = countup(n - 1); countArray.push(n);la constse reasigna cada vez. Entonces, ¿por qué usar consty no var?
YCode
1
@YCode no. cuando lo use const countArray, nunca será reasignado. Todavía puede presionar a la matriz, que cambia sus miembros y longitud, pero no llamamos a eso reasignación. utiliza en constlugar de leto varcuando desea evitar la reasignación. Por cierto, si usted no desea permitir la reasignación, letes casi siempre mejor que var.
chharvey
@chharvey Gracias! Su respuesta me llevó a "pasar por valor frente a pasar por referencia", un concepto nuevo y extraño, donde la modificación del valor ≠ reasignación. Cualquier persona que necesite más explicaciones debe consultar las respuestas aquí: stackoverflow.com/q/46131828/5965865
YCode
38

Para integrar las respuestas anteriores, hay una ventaja obvia en declarar variables constantes, además de la razón de rendimiento: si accidentalmente intenta cambiarlas o volver a declararlas en el código, el programa no cambiará el valor ni arrojará un error.

Por ejemplo, compare:

// Will output 'SECRET'

const x = 'SECRET'
if (x = 'ANOTHER_SECRET') {  // Warning! assigning a value variable in an if condition
    console.log (x)
}

con:

// Will output 'ANOTHER_SECRET'

var y = 'SECRET'
if (y = 'ANOTHER_SECRET') { 
    console.log (y)
}

o

// Will throw TypeError: const 'x' has already been declared

const x = "SECRET"

/*  complex code */

var x = 0

con

// Will reassign y and cause trouble

var y = "SECRET"

/*  complex code */

var y = 0
janesconference
fuente
Debería decir que este comportamiento "inmutable" solo es aplicable a cadenas, tipos básicos. Usando objetos, matrices, etc., es posible cambiar los valores, pero no es posible reasignar un nuevo "Objeto", por ejemplo, const a = ["a", "b"]; a = []; arrojará un error de lo contrario es posible
Fer Al
Debería tener un ejemplo donde intente y cambie el valor de una constante también.
Joshua Pinter
El uso de const es muy similar a los modificadores de acceso, la verdadera inmutabilidad no es el objetivo.
StingyJack
32

constNo es inmutable.

De la MDN :

La declaración const crea una referencia de solo lectura a un valor. No significa que el valor que posee es inmutable, solo que el identificador de variable no se puede reasignar.

Antonio
fuente
24
Sin embargo, eso es un poco engañoso. Para números, cadenas, booleanos, etc. (primitivas) constes inmutable. Para objetos y matrices no se puede reasignar, pero se puede cambiar el contenido (por ejemplo, array.push).
Florian Wendelborn
2
Sin embargo, las primitivas JS son siempre inmutables. Si lo usas consto no no afecta eso.
12Me21
1
@Dodekeract, por lo tanto, no es inmutable por definición. Si los valores pueden cambiar, no es inmutable, aunque funciona como inmutable para las primitivas que ha enumerado
Anthony
13

var : declara una variable, inicialización del valor opcional.

let : Declara una variable local con alcance de bloque.

const : declara una constante llamada de solo lectura.

Ex:

var a;
a = 1;
a = 2;//re-initialize possible
var a = 3;//re-declare
console.log(a);//3

let b;
b = 5;
b = 6;//re-initiliaze possible
// let b = 7; //re-declare not possible
console.log(b);

// const c;
// c = 9;   //initialization and declaration at same place
const c = 9;
// const c = 9;// re-declare and initialization is not possible
console.log(c);//9
// NOTE: Constants can be declared with uppercase or lowercase, but a common
// convention is to use all-uppercase letters.
Srikrushna
fuente
10

Tienes excelentes respuestas, pero seamos simples.

const debe usarse cuando tiene una constante definida (leída como: no cambiará durante la ejecución de su programa).

Por ejemplo:

const pi = 3.1415926535

Si cree que es algo que se puede cambiar en una ejecución posterior, utilice a var.

La diferencia práctica, basada en el ejemplo, es que constsiempre supondrá que pi será 3.14 [...], es un hecho.

Si lo define como a var, podría ser 3.14 [...] o no.

Para una respuesta más técnica, @Tibos tiene razón académica.

Edgar Griñant
fuente
7

En mi experiencia, uso const cuando quiero configurar algo que quiera cambiar más tarde sin tener que buscar en el código buscando bits que hayan sido codificados, por ejemplo, una ruta de archivo o un nombre de servidor.

Sin embargo, el error en su prueba es otra cosa, está tratando de hacer otra variable llamada x, esta sería una prueba más precisa.

const x = 'const';
x = 'not-const';
Funkotron_King
fuente
99
Entiendo lo que quieres decir, pero es gracioso que "constante" para ti significa "algo que podría querer cambiar". : P
Venryx
4

Preferencia personal realmente. Puede usar const cuando, como usted dice, no se reasignará y es constante. Por ejemplo, si desea asignar su cumpleaños. Su cumpleaños nunca cambia, por lo que podría usarlo como una constante. Pero su edad cambia, por lo que podría ser una variable.

Carl Markham
fuente
17
¡Ese sería un script muy largo!
nulabilidad
3
@nullability Depende de la edad de las personas que está rastreando. Más de unas pocas docenas y el script no tendrá que ejecutarse por mucho tiempo :).
Millie Smith
4

Resumen:

const crea un enlace inmutable, lo que significa que el identificador de variable const no se puede reasignar.

const a = "value1";

no puedes reasignarlo con

a = "value2";

Sin embargo, si el identificador const contiene un objeto o una matriz, su valor puede cambiarse siempre que no lo reasignemos.

const x = { a: 1 }

x.a = 2; //is possible and allowed

const numbers = [1, 2];
numbers.push(3); //is possible and allowed

Tenga en cuenta que const tiene un ámbito de bloque como let, que no es lo mismo que var (que tiene un ámbito de función)

En resumen, cuando no es probable que algo cambie a través de la reasignación, use const else use let o var dependiendo del alcance que le gustaría tener.

Es mucho más fácil razonar sobre el código cuando es obvio qué se puede cambiar mediante la reasignación y qué no. Cambiar una constante a una let es muy simple. Y seguir const por defecto te hace pensar dos veces antes de hacerlo. Y esto es en muchos casos algo bueno.

Tejas Patel
fuente
2
Main point is that how to decide which one identifier should be used during development.
In java-script here are three identifiers.

1. var (Can re-declared & re-initialize)
2. const (Can't re-declared & re-initialize, can update array values by using push)
3. let (Can re-initialize but can't re-declare)

'var': en el momento de la codificación cuando hablamos de código estándar, usualmente usamos el nombre del identificador, que es fácil de entender por otro usuario / desarrollador. Por ejemplo, si estamos trabajando, pensamos en muchas funciones donde usamos alguna entrada y procesamos esto y devolvemos algún resultado, como:

**Example of variable use**

function firstFunction(input1,input2)
{
 var process = input1 + 2; 
 var result = process - input2;
 return result;
}


function otherFunction(input1,input2)
{
 var process = input1 + 8; 
 var result = process * input2;
 return result;
}

En los ejemplos anteriores, ambas funciones producen resultados de 2 diferentes pero usan el mismo nombre de variables. Aquí podemos ver 'proceso' y 'resultado', ambos se usan como variables y deberían serlo.

 **Example of constant with variable**

 const tax = 10; 
 const pi = 3.1415926535; 

function firstFunction(input1,input2)
{
 var process = input1 + 2; 
 var result = process - input2;
 result = (result * tax)/100; 
 return result;
}


function otherFunction(input1,input2)
{
 var process = input1 + 8; 
 var result = process * input2 * pi;
 return result;
}

Antes de usar 'let' en java-script tenemos que agregar 'use estricto' en la parte superior del archivo js

 **Example of let with constant & variable**

 const tax = 10; 
 const pi = 3.1415926535; 
 let trackExecution = '';

function firstFunction(input1,input2)
{
 trackExecution += 'On firstFunction'; 
 var process = input1 + 2; 
 var result = process - input2;
 result = (result * tax)/100; 
 return result;
}


function otherFunction(input1,input2)
{
 trackExecution += 'On otherFunction'; # can add current time 
 var process = input1 + 8; 
 var result = process * input2 * pi;
 return result;
}

 firstFunction();
 otherFunction();
 console.log(trackExecution);

En el ejemplo anterior, puede rastrear qué función se ejecutó cuándo y qué función no se utilizó durante una acción específica.

vinod
fuente
1

Primero, tres cosas útiles sobre const(además de las mejoras de alcance con las que comparte let):

  • Documenta para las personas que leen el código más tarde que el valor no debe cambiar.
  • Evita que usted (o cualquier persona que vaya detrás de usted) cambie el valor a menos que regrese y cambie la declaración intencionalmente.
  • Se puede guardar el motor de JavaScript algunos análisis en términos de optimización. Por ejemplo, ha declarado que el valor no puede cambiar, por lo que el motor no tiene que hacer un trabajo para determinar si el valor cambia para poder decidir si se optimiza en función del valor que no cambia.

Tus preguntas:

¿Cuándo es apropiado usar consten lugar de var?

Usted puede hacerlo en cualquier momento usted está declarando una variable cuyo valor no cambia nunca. Si considera que lo apropiado depende de sus preferencias o las preferencias de su equipo.

¿Debería usarse cada vez que se declara una variable que no se va a reasignar?

Eso depende de usted / su equipo.

¿Realmente hace alguna diferencia si var is used in place ofconst` o viceversa?

Si:

  • vary consttienen diferentes reglas de alcance. (Es posible que haya querido comparar en letlugar de hacerlo var). Específicamente: consty lettienen un alcance de bloque y, cuando se usan en el ámbito global, no crean propiedades en el objeto global (a pesar de que crean globales). vartiene alcance global (cuando se usa en alcance global) o alcance de función (incluso si se usa en un bloque), y cuando se usa en alcance global, crea una propiedad en el objeto global.
  • Vea mis "tres cosas útiles" arriba, todas se aplican a esta pregunta.
TJ Crowder
fuente
1

La semántica de varylet

vary letson una declaración para la máquina y para otros programadores:

Tengo la intención de que el valor de esta asignación cambie en el transcurso de la ejecución. No confíe en el valor eventual de esta asignación.

Implicaciones de usar varylet

vary letobligar a otros programadores a leer todo el código intermedio desde la declaración hasta el uso final, y razonar sobre el valor de la asignación en ese punto de la ejecución del programa.

Debilitan el razonamiento de la máquina para que ESLint y otros servicios de idiomas detecten correctamente los nombres de variables mal escritas en asignaciones posteriores y la reutilización del alcance de los nombres de variables de alcance externo donde el alcance interno olvida declarar.

También hacen que los tiempos de ejecución ejecuten muchas iteraciones en todas las rutas de código para detectar que en realidad son, de hecho, constantes, antes de poder optimizarlas. Aunque esto es menos problemático que la detección de errores y la comprensión del desarrollador.

Cuándo usar const

Si el valor de la referencia no cambia en el transcurso de la ejecución, la sintaxis correcta para expresar la intención del programador es const. Para los objetos, cambiar el valor de la referencia significa apuntar a otro objeto, ya que la referencia es inmutable, pero el objeto no.

" const" objetos

Para referencias de objeto, el puntero no se puede cambiar a otro objeto, pero el objeto que se crea y se asigna a una constdeclaración es mutable. Puede agregar o eliminar elementos de una constmatriz a la que se hace referencia y mutar claves de propiedad en un constobjeto referenciado.

Para lograr objetos inmutables (que de nuevo, hacen que su código sea más fácil de razonar para humanos y máquinas), puede hacer Object.freezeel objeto en la declaración / asignación / creación, de esta manera:

const Options = Object.freeze(['YES', 'NO'])

Object.freeze tiene un impacto en el rendimiento, pero su código probablemente sea lento por otras razones. Quieres perfilarlo.

También puede encapsular el objeto mutable en una máquina de estado y devolver copias profundas como valores (así es como funcionan los estados de Redux y React). Consulte Evitar el estado global mutable en Browser JS para ver un ejemplo de cómo construir esto desde los primeros principios.

Cuando vary letson un buen partido

lety varrepresentan estado mutable. En mi opinión, solo deberían usarse para modelar el estado mutable real . Cosas como "¿ está viva la conexión? ".

Estos se encapsulan mejor en máquinas de estado comprobables que exponen valores constantes que representan " el estado actual de la conexión ", que es una constante en cualquier momento, y en lo que está realmente interesado el resto del código.

La programación ya es bastante difícil con la composición de efectos secundarios y la transformación de datos. Convertir cada función en una máquina de estado no comprobable creando un estado mutable con variables que solo acumulan la complejidad.

Para una explicación más matizada, vea Shun the Mutant - The case forconst .

Josh Wulf
fuente
0

No soy un experto en el negocio de compilación de JS, pero tiene sentido decir que v8 hace uso de la bandera constante

Normalmente, después de declarar y cambiar un montón de variables, la memoria se fragmenta y v8 se detiene para ejecutarse, hace una pausa de unos segundos para hacer gc o recolección de basura.

Si una variable se declara con const v8, puede confiar en colocarla en un contenedor de tamaño fijo ajustado entre otras variables const, ya que nunca cambiará. También puede guardar las operaciones adecuadas para esos tipos de datos, ya que el tipo no cambiará.

judío
fuente
0

Cuando se trata de la decisión entre let y const , siempre prefiera const para que el uso sea claro en el código. De esa manera, si intenta redeclarar la variable, obtendrá un error. Si no hay otra opción más que redeclararlo, simplemente cambie para alquilar . Tenga en cuenta que, como dice Anthony , los valores no son inmutables (por ejemplo, un objeto const puede tener propiedades mutadas).

Cuando se trata de var , dado que ES6 está fuera, nunca lo usé en el código de producción y no puedo pensar en un caso de uso para él. Sin embargo, tenga en cuenta que las variables declaradas con var no tienen alcance de bloque.

Tiago Martins Peres 李大仁
fuente