Quiz

Explique a diferença entre objetos mutáveis e imutáveis

Topics
JavaScript
Edit on GitHub

A imutabilidade é um princípio central na programação funcional e também tem muito a oferecer para programas orientados para objetos. Um objeto mutável é um objeto cujo estado pode ser modificado depois de criado. Um objeto mutável é um objeto cujo estado pode ser modificado depois de criado.

O que é um exemplo de um objeto imutável em JavaScript?

Em JavaScript, alguns tipos internos (números, strings) são imutáveis, mas objetos personalizados geralmente são mutáveis.

Alguns objetos JavaScript imutáveis integrados são Math, Date.

Aqui estão algumas maneiras de adicionar/simular imutabilidade em objetos JavaScript simples.

Propriedades Constante de Objeto

Ao combinar gravável: falso e configurável: falso, você pode criar uma constante (não pode ser alterada, redefinida ou apagada) como uma propriedade do objeto, como:

let myObject = {};
Object.defineProperty(myObject, 'number', {
value: 42,
writable: false,
configurable: false,
});
console.log(myObject.number); // 42
myObject.number = 43;
console.log(myObject.number); // 42

Evitar Extensões

Se você quiser evitar que um objeto tenha novas propriedades adicionadas, mas deixando o resto das propriedades do objeto sozinhas, chame Object.preventExtensions(...):

let myObject = {
a: 2,
};
Object.preventExtensions(myObject);
myObject.b = 3;
myObject.b; // undefined

No modo não restrito, a criação de b falha silenciosamente. No modo estrito, ele lança um TypeError.

Proteção

Object.seal() cria um objeto "selado", o que significa que recebe um objeto existente e basicamente chama Object.preventExtensions() nele, mas também marca todas as suas propriedades existentes como configurable: false.

Então, não só você não pode adicionar mais propriedades, mas você também não pode reconfigurar ou apagar quaisquer propriedades existentes (embora você ainda possa modificar seus valores).

Travamento

Object.freeze() cria um objeto congelado, o que significa que é preciso um objeto existente e basicamente chama objeto.seal() nele, mas também marca todas as propriedades do tipo "acesso a dados" como writable:false, para que seus valores não possam ser alterados.

Essa abordagem é o maior nível de imutabilidade que você pode alcançar para um objeto em si, pois impede quaisquer mudanças no objeto ou em qualquer uma de suas propriedades diretas (embora, como mencionado acima, o conteúdo de quaisquer outros objetos referenciados não seja afetado).

let immutableObject = Object.freeze({});

Congelar um objeto não permite que novas propriedades sejam adicionadas a um objeto e impede que os usuários removam ou modifiquem as propriedades existentes. Object.freeze() preserva a enumerabilidade, configurabilidade, gravabilidade e protótipo do objeto. Ele retorna o objeto passado e não cria uma cópia congelada.

Quais são os prós e os contras da imutabilidade?

Prós

  • Detecção de mudanças mais fácil: A igualdade de objetos pode ser determinada de maneira eficiente e fácil por meio da igualdade referencial. Isso é útil para comparar diferenças de objetos no React e Redux.
  • Menos complicado: Programas com objetos imutáveis são menos complicados de se pensar, já que você não precisa se preocupar sobre como um objeto pode evoluir ao longo do tempo.
  • Compartilhamento fácil por referências: Uma cópia de um objeto é tão boa quanto outra, então você pode armazenar objetos em cache ou reutilizar o mesmo objeto várias vezes.
  • Seguro para threads: Objetos imutáveis podem ser usados com segurança entre threads em um ambiente multi-threaded, já que não há risco de serem modificados em outras threads que estão sendo executadas simultaneamente.
  • Menos necessidade de memória: Usando bibliotecas como Immer e Immutable.js, objetos são modificados usando compartilhamento estrutural e menos memória é necessária para ter vários objetos com estruturas semelhantes.
  • Não há necessidade de cópias defensivas: cópias defensivas não são mais necessárias quando objetos imutáveis são retornados ou passados para funções, uma vez que não há possibilidade de um objeto imutável ser modificado por ela.

Contras

  • Complexo para criar por si mesmo: Implementações ingênuas de estruturas de dados imutáveis e suas operações podem resultar em desempenho extremamente pobre porque novos objetos são criados cada vez. É recomendado o uso de bibliotecas para estruturas de dados imutáveis e operações eficientes que utilizam compartilhamento estrutural.
  • Potencial impacto negativo na performance: Alocação (e desalocação) de muitos objetos pequenos ao invés de modificar objetos existentes pode causar um impacto na performance. A complexidade do alocador ou do coletor de lixo geralmente depende do número de objetos no heap.
  • Complexidade para estruturas de dados cíclicas: estruturas de dados cíclicas como grafos são difíceis de construir. Se você tiver dois objetos que não podem ser modificados após a inicialização, como você pode fazer com que eles apontem um para o outro?
Edit on GitHub