¿Por qué puedo cambiar un objeto constante en JavaScript?

Resuelto Salvador Dali asked hace 10 años • 13 respuestas

Sé que ES6 aún no está estandarizado, pero actualmente muchos navegadores lo admiten. const palabras clave en JS.

En especificaciones, está escrito que:

El valor de una constante no puede cambiar mediante la reasignación y una constante no se puede volver a declarar. Por esto, aunque es posible declarar una constante sin inicializarla, sería inútil hacerlo.

y cuando hago algo como esto:

const xxx = 6;
xxx = 999;
xxx++;
const yyy = [];
yyy = 'string';
yyy = [15, 'a'];

Veo que todo está bien: xxxestá quieto 6y yyyestá[] .

Pero si lo hago yyy.push(6); yyy.push(1); , mi matriz constante ha cambiado. Ahora mismo lo es [6, 1]y por cierto todavía no puedo cambiarlo conyyy = 1; .

¿Es esto un error o me falta algo? Lo probé en la última versión de Chrome y FF29.

Salvador Dali avatar May 03 '14 03:05 Salvador Dali
Aceptado

La documentación de MDN dice:

...la constante no puede cambiar mediante reasignación
...la constante no puede volver a declararse

Cuando agrega una matriz u objeto, no reasigna ni declara la constante; ya está declarado y asignado. Simplemente estás agregando a la lista de elementos o propiedades a las que apunta la constante.

Entonces esto funciona bien:

const x = {};

x.foo = 'bar';

console.log(x); // {foo : 'bar'}

x.foo = 'bar2';

console.log(x); // {foo : 'bar2'}  

y esto:

const y = [];

y.push('foo');

console.log(y); // ['foo']

y.unshift("foo2");

console.log(y); // ['foo2', 'foo']

y.pop();

console.log(y); // ['foo2']

pero ninguno de estos:

const x = {};
x = {foo: 'bar'}; // error - re-assigning

const y = ['foo'];
const y = ['bar']; // error - re-declaring

const foo = 'bar'; 
foo = 'bar2';       // error - can not re-assign
var foo = 'bar3';   // error - already declared
function foo() {};  // error - already declared
adeneo avatar May 02 '2014 20:05 adeneo

Esto sucede porque su constante en realidad almacena una referencia a la matriz. Cuando unes algo a tu matriz no estás modificando tu valor constante, sino la matriz a la que apunta. Lo mismo sucedería si asignaras un objeto a una constante e intentaras modificar alguna de sus propiedades.

Si desea congelar una matriz u objeto para que no pueda modificarse, puede utilizar el Object.freezemétodo, que ya forma parte de ECMAScript 5.

const x = Object.freeze(['a'])
x.push('b')
console.log(x) // ["a"]
Guilherme Sehn avatar May 02 '2014 20:05 Guilherme Sehn