Imutabilidade no ES6

Publicação: | Tags: JavaScript, Node.js

Imutabilidade no ES6

Caso você já esteja por dentro sobre o ES6/7/8/9/100000, você já deve estar bem ciente de como trabalhar com imutabilidade usando a keyword const para declarar varíaveis imútaveis. De fato não há nenhum segredo nisso, basicamente você declara qualquer tipo de dados usando const e nunca mais seu estado inicial será modificado, correto? Veja esse exemplo:

const score = 10;
console.log(score); // 10

score = 9; // TypeError: Assignment to constant variable

Até aqui tudo ok, foi criado uma constante score com valor 10, e ao tentar modificar seu valor para 9, ocorreu o erro: TypeError: Assignment to constant variable, que basicamente é um erro referente a não permissão de mudança de valores em uma variável que já possui um valor.

Outro detalhe da const, você não pode criá-la sem definir um valor, pois vai gerar o seguinte erro:

const score; // SyntaxError: Missing initializer in const declaration

É regra básica, não se pode criar constante sem definir seu estado inicial, pois undefined não é uma definição de um bom estado, não é?

Porém voltando a pergunta inicial, usar const torna qualquer tipo de dado do JavaScript imutável? NÃO!
Somente dados primitivos: String, Number, Date, Boolean, serão imútaveis, se você usar objeto ou array, facilmente você poderá modificar os atributos internos deles, o que teoricamente deveria ser imútavel também.

const scores = [];
scores.push(1);
scores.push(3);
scores.push(4);
console.log(scores); /// [1, 3, 4]

O mesmo cenário ocorre para objetos:

const player = {};
player.name = 'John Connor';
player.age = 25;
console.log(player); // { name: 'John Connor', age: 25 }

Nestes dois cenários, seus atributos internos foram modificados e nenhum erro ocorreu, afinal o const somente torna imútavel as atribuições das variáveis, ou seja, tudo aquilo que for atribuído usando = na inicialização de uma variável, qualquer atribuição em propriedades de um objeto serão ignorados.

Como tornar objetos e arrays imútaveis??

Desde o ES5, já existia uma função chamada Object.freeze() que congela o estado interno de um objeto ou array, ou seja, seus atributos jamais serão modificados, congelando seu estado, e não permitindo a inclusão, alteração e exclusão de seus atributos internos, entenda nesse exemplo:

const player = { name: 'John Connor' };
Object.freeze(player);
// Silenciosamente não vai acontecer nenhum erro
player.age = 25; 
// Porém não será incluído o atributo age no objeto que foi congelado!
console.log(player); // Object { name: 'John Connor' }

No caso do array, qualquer modificação vai gerar um erro, veja:

const scores = [1, 2, 3];
Object.freeze(scores);
scores.push(10); // TypeError: Can't add property 10, object is not extensible

Caso seja necessário visualizar um erro na modificação de um objeto, basta usar 'use strict' no topo do código:

'use strict';
const player = { name: 'John Connor' };
Object.freeze(player);
player.age = 25; // TypeError: Can't add property age, object is not extensible

Conclusão

Se você pretende trabalhar 100% com dados imútaveis e isso inclui tanto dados primitivos quanto objetos e arrays, basta usar const para as variáveis primitivas e const + Object.freeze() para objetos e ou arrays.

Fonte: MDN - Object.freeze()

Compartilhe este post