DEV Community

Neto Jocelino
Neto Jocelino

Posted on

2

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).

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up