DEV Community

Neto Jocelino
Neto Jocelino

Posted on

Objetos imutáveis em JS

Este post é apenas uma nota sobre a postagem em JSTips e a thread do Felippe Regazio acerca do tópico.

Para iniciar é importante entender que objetos imutáveis referem-se à objetos que não devem ser modificados. Ou seja, após a criação o objeto passa a ter propriedade de apenas leitura.

Vejamos o objeto abaixo, onde possui informações de redes sociais, após a criação não é possível alterar SocialMedia, porém é possível alterar as informações internas - assim como inserir novas.

const SocialMedia = {
  'dev.to': 'https://dev.to/netojocelino',
  'github': 'https://github.com/netojocelino',
  'linkedin': 'https://www.linkedin.com/in/netojocelino',
  'snippets': 'https://gist.github.com/netojocelino',
}
Enter fullscreen mode Exit fullscreen mode

Caso tente modificar o valor de SocialMedia, como SocialMedia = null, o erro abaixo será lançado
Uncaught TypeError: invalid assignment to const 'SocialMedia'.

Para tornar objetos mais restritivos à edição, também é possível adicionar prevenção à extensões, ou seja, adição de novas propriedades.

Desta forma, imaginemos o mesmo objeto. Porém, após a criação adiciona-se uma restrição à adição de novas propriedades, não gerando erro para criar, porém não insere uma nova propriedade.

const SocialMedia = {
  'dev.to': 'https://dev.to/netojocelino',
  'github': 'https://github.com/netojocelino',
  'linkedin': 'https://www.linkedin.com/in/netojocelino',
  'snippets': 'https://gist.github.com/netojocelino',
} // { 'dev.to': '...', 'github': '...', 'linkedin': '...', 'snippets': '...' }

Object.preventExtensions(SocialMedia)

SocialMedia.gitlab = 'https://gitlab.com/netojocelino' // { 'dev.to': '...', 'github': '...', 'linkedin': '...', 'snippets': '...' } 
Enter fullscreen mode Exit fullscreen mode

É importante notar que ainda será possível editar ou remover alguma propriedade já existente.
Assim, caso seja utilizado o trecho SocialMedia.snippets = 'https://codepen.io/netojocelino/pens' o objeto será modificado, e caso remova uma propriedade com delete SocialMedia['dev.to'] ainda surtirá efeito.

// { 'github': '...', 'linkedin': '...', 'snippets': 'https://codepen.io/netojocelino/pens' }
Enter fullscreen mode Exit fullscreen mode

Para prevenir modificações como edição ou remoção é possível utilizar Object.seal(SocialMedia).
Desta forma, caso tenha tentativa de edição, SocialMedia.snippets = 'https://codepen.io/netojocelino/pens' ou remoção delete SocialMedia['dev.to'] o objeto não será alterado.

// { 'dev.to': '', 'github': '...', 'linkedin': '...', 'snippets': '...' }
Enter fullscreen mode Exit fullscreen mode

Para bloquear também as adições, é necessário utilizar Object.freeze(SocialMedia), que bloqueia tanto a remoção, edição e também a adição de novas propriedades, fazendo SocialMedia.telegram = 'https://t.me/netojocelino' não ser adicionado ao objeto, mantendo a estrutura de

// { 'dev.to': '', 'github': '...', 'linkedin': '...', 'snippets': '...' }
Enter fullscreen mode Exit fullscreen mode

Todas estas propriedades podem ser checadas, de forma que Object.isExtensible(SocialMedia) retorna um booleano true caso seja possível adicionar novas propriedades no objeto e false caso não possa ser extensível. O retorno de Object.isSealed(SocialMedia) retorna true quando é prevenido a adição ou remoção de propriedades do objeto e false quando é possível adicionar ou remover. O método Object.isFrozen(SocialMedia) indica caso não for possível alterar de forma alguma alguma propriedade.

Resumo:

  • Mesmo um objeto definido como constante pode sofrer algum tipo de mutação interna.
  • É possível restringir adição de novas propriedades com Object.preventExtensions(myObject). Para conferir se está com restrição, use Object.isExtensible(myObject) (true para bloqueado a adição).
  • É possível restringir edição e remoção de propriedades com Object.seal(myObject). Para conferir se está com restrição, use Object.isSealed(myObject) (true para bloqueado a edição e remoção).
  • É possível restringir adição, edição e remoção de propriedades com Object.freeze(myObject). Para conferir se está com restrição, use Object.isFrozen(myObject) (true para bloqueado qualquer manipulação).

Top comments (0)