W3docs

Descritores de Propriedades JavaScript

Aprenda como flags e descritores de propriedades JavaScript (writable, enumerable, configurable) funcionam, incluindo defineProperty, getOwnPropertyDescriptors, freeze, seal e strict mode.

As flags e descritores de propriedades do JavaScript oferecem controle preciso sobre as propriedades de objetos, permitindo o desenvolvimento de aplicações robustas e seguras. Este artigo explora esses recursos em detalhes, fornecendo insights práticos e exemplos de código para ajudá-lo a gerenciar eficazmente o comportamento das propriedades.

Compreendendo os Atributos de Propriedades do JavaScript

Objetos JavaScript são coleções de propriedades, e cada propriedade possui atributos associados que definem seu comportamento. Esses atributos, frequentemente chamados de flags de propriedade, incluem:

  • Writable: Determina se o valor da propriedade pode ser alterado.
  • Enumerable: Controla se a propriedade é visível durante a enumeração, como em um loop for...in.
  • Configurable: Especifica se a propriedade pode ser excluída ou modificada.

Essas flags são fundamentais para controlar o acesso às propriedades do objeto, garantindo a integridade dos dados e implementando encapsulamento em aplicações JavaScript.

Explorando os Descritores de Propriedades

Os descritores de propriedades fornecem informações detalhadas sobre a propriedade de um objeto, encapsulando seu valor e flags. Eles são recuperados usando Object.getOwnPropertyDescriptor(obj, propName) e definidos usando Object.defineProperty(obj, propName, descriptor). Um objeto descritor de propriedade pode conter:

  • value: O valor associado à propriedade.
  • writable: Indica se o valor da propriedade pode ser alterado.
  • enumerable: Indica se a propriedade é enumerável.
  • configurable: Determina se o descritor da propriedade pode ser alterado e se a propriedade pode ser excluída do objeto.

Observação: Quando você cria uma propriedade da forma normal (user.name = "John"), as três flags são definidas como true. Mas ao definir uma nova propriedade via Object.defineProperty, qualquer flag não especificada tem como padrão false.


javascript— editable

Object.getOwnPropertyDescriptor analisa apenas as propriedades próprias do objeto. Se você consultar uma propriedade que o objeto herda de seu protótipo (ou uma propriedade que não existe), ele retorna undefined.


javascript— editable

Para saber mais sobre como os objetos herdam propriedades, veja Herança Prototípica.

Descritores de Dados vs. Descritores de Acesso

Até agora descrevemos descritores de dados, que armazenam um value junto com a flag writable. O JavaScript também suporta descritores de acesso, que substituem value/writable por funções getter e setter:

  • get: uma função chamada quando a propriedade é lida (não recebe argumentos).
  • set: uma função chamada quando a propriedade é atribuída (recebe o novo valor).

Um descritor é ou um descritor de dados ou um descritor de acesso — nunca os dois ao mesmo tempo. Combinar value/writable com get/set lança um erro. Ambos os tipos ainda compartilham as flags enumerable e configurable.

As propriedades de acesso são a forma de computar um valor na leitura ou validá-lo na escrita. Aqui expõemos um acessor fullName baseado em duas propriedades de dados:


javascript— editable

Para um tratamento mais completo da sintaxe get/set (incluindo a forma abreviada dentro de literais de objeto), veja Getters e Setters de Propriedades. Como getters e setters são executados com this vinculado ao objeto, também é útil entender Métodos de Objeto e "this".

Definindo e Lendo Várias Propriedades de Uma Vez

Para trabalhar com várias propriedades em um único passo, o JavaScript fornece os equivalentes plurais dos métodos acima:

  • Object.defineProperties(obj, descriptors) define múltiplas propriedades a partir de um mapa de descritores.
  • Object.getOwnPropertyDescriptors(obj) retorna os descritores de todas as propriedades próprias (incluindo não enumeráveis e chaves symbol) como um único objeto.

Object.getOwnPropertyDescriptors é especialmente útil para clonar um objeto com suas flags — um spread simples ou Object.assign copia valores, mas redefine todas as flags como true e ignora os acessores.


javascript— editable

Manipulando Flags de Propriedades

Compreender e manipular flags de propriedades é fundamental para um desenvolvimento JavaScript eficaz. Vamos explorar como controlar essas flags para ajustar finamente o comportamento das propriedades.

Tornando uma Propriedade Não-gravável

Impedir modificações em uma propriedade garante a consistência dos dados. Isso pode ser feito definindo a flag writable como false.


javascript— editable

O comportamento da atribuição falha depende do modo em que o código é executado. No modo não-strict, escrever em uma propriedade não-gravável falha silenciosamente: a atribuição é simplesmente ignorada, nenhum erro é lançado e a execução continua — o que pode ocultar bugs. No modo strict ("use strict", e o padrão dentro de módulos ES e corpos de classe), a mesma atribuição lança um TypeError. A regra se aplica a qualquer operação que viole uma flag: excluir uma propriedade não-configurável ou adicionar uma propriedade a um objeto não-extensível também falha silenciosamente no modo não-strict e lança no modo strict.


javascript— editable

Ocultando uma Propriedade da Enumeração

Às vezes, é necessário ocultar propriedades dos processos de enumeração, como loops for...in. Isso pode ser feito definindo a flag enumerable como false.


javascript— editable

Impedindo a Exclusão e Modificação de Propriedades

Para garantir que uma propriedade permaneça uma parte constante de um objeto, defina a flag configurable como false.


javascript— editable

Marcar uma propriedade como não-configurável é uma operação irreversível — não há flag para torná-la configurável novamente, e você não pode mais alternar enumerable ou converter a propriedade entre um descritor de dados e um descritor de acesso.

No entanto, há duas exceções importantes enquanto uma propriedade é não-configurável:

  • Você pode alterar writable de true para false (mas não de volta de false para true).
  • Se a propriedade ainda for writable: true, você pode alterar seu value — seja por atribuição direta ou via Object.defineProperty.

Em outras palavras, configurable: false bloqueia a forma da propriedade, mas não necessariamente seu valor. Para verdadeiramente congelar o valor de uma propriedade, defina tanto configurable: false quanto writable: false.


javascript— editable

APIs de Alto Nível Baseadas nessas Flags

Raramente é necessário definir flags uma propriedade por vez. O JavaScript fornece três métodos embutidos que alteram essas flags em um objeto inteiro:

  • Object.preventExtensions(obj) — impede que novas propriedades sejam adicionadas. As propriedades existentes ainda podem ser alteradas ou excluídas.
  • Object.seal(obj) — impede adicionar e excluir propriedades, marcando cada propriedade existente como configurable: false. Os valores ainda podem ser alterados.
  • Object.freeze(obj) — o mais restritivo: sela o objeto e torna cada propriedade writable: false, de modo que nada pode ser adicionado, removido ou alterado.

Cada método possui uma verificação correspondente: Object.isExtensible, Object.isSealed e Object.isFrozen. Observe que esses operam em apenas um nível — Object.freeze não congela objetos aninhados (é um congelamento "superficial").


javascript— editable

Conclusão

Flags e descritores de propriedades oferecem controle preciso sobre como as propriedades de objeto se comportam:

  • Um descritor de dados combina um value com writable; um descritor de acesso usa funções get/set em vez disso. Ambos compartilham enumerable e configurable.
  • Leia flags com Object.getOwnPropertyDescriptor (uma propriedade) ou Object.getOwnPropertyDescriptors (todas as propriedades próprias); escreva-as com Object.defineProperty ou Object.defineProperties. Propriedades herdadas e ausentes retornam undefined.
  • configurable: false é irreversível e bloqueia a forma da propriedade, embora uma propriedade ainda writable possa ter seu valor alterado e sua flag writable desativada.
  • Violar uma flag falha silenciosamente no modo não-strict, mas lança um TypeError no modo strict.
  • Use Object.freeze, Object.seal e Object.preventExtensions quando quiser bloquear um objeto inteiro em vez de flags individuais.

Próximos passos: aprofunde-se em Getters e Setters de Propriedades para a sintaxe de acessor, Métodos de Objeto e "this" para como this se comporta dentro deles, e Herança Prototípica para ver como a busca de propriedades percorre a cadeia de protótipos.

Prática

Prática
Em JavaScript, quais são as características que podem ser definidas por descritores de propriedades?
Em JavaScript, quais são as características que podem ser definidas por descritores de propriedades?
Was this page helpful?