O que sabes sobre os descritores?
sobes.tech IA
Resposta da IA
Os descritores em JavaScript são objetos que descrevem várias propriedades de uma propriedade de um objeto, como o seu valor (value), a possibilidade de escrita (writable), a possibilidade de enumeração (enumerable) e a possibilidade de configuração (configurable). Existem também descritores com getters e setters.
Existem dois tipos de descritores:
-
Descritores de dados: Contêm o valor da propriedade.
value: O valor da propriedade. Pode ser de qualquer tipo de dado válido.writable: Um valor booleano. Se fortrue, o valor da propriedade pode ser alterado (obj.prop = newValue). Por padrão, éfalsepara propriedades de acesso etruepara propriedades de dados criadas por atribuição normal.enumerable: Um valor booleano. Se fortrue, a propriedade será visível durante a iteração sobre as propriedades do objeto (por exemplo, em um ciclofor...inou usandoObject.keys()). Por padrão, éfalsepara propriedades adicionadas comObject.definePropertyetruepara propriedades criadas por atribuição normal.configurable: Um valor booleano. Se fortrue, as características do descritor (excetovalueewritablequando mudam de dados para acessórios) podem ser modificadas, e a propriedade pode ser eliminada. Por padrão, éfalsepara propriedades adicionadas comObject.defineProperty(excetovalue) etruepara propriedades criadas por atribuição normal. Uma vez configurado como não configurável, não pode ser alterado novamente. Pode diminuir a writable de true para false, mas não o contrário num getter/setter não configurável.
-
Descritores de acessórios: Definem funções que serão chamadas ao obter (getter) ou definir (setter) o valor da propriedade.
get: Função chamada ao ler a propriedade. O resultado desta função torna-se o valor da propriedade. Não aceita argumentos.set: Função chamada ao escrever na propriedade. Aceita um argumento, que é o novo valor a definir.enumerable: Um valor booleano (semelhante aos descritores de dados).configurable: Um valor booleano (semelhante aos descritores de dados).
Não se devem misturar descritores: uma propriedade tem ou value e writable, ou get e set.
Descritores são usados para gerir as propriedades de um objeto a um nível mais baixo do que a atribuição normal, em particular através dos métodos Object.defineProperty(), Object.defineProperties(), Object.getOwnPropertyDescriptor(), Object.getOwnPropertyDescriptors(), Object.create().
Exemplo de criação de uma propriedade com um descritor de dados:
// Criar um objeto vazio
const obj = {};
// Definir a propriedade 'name' com um descritor de dados
Object.defineProperty(obj, 'name', {
value: 'Alice',
writable: false, // A propriedade não pode ser alterada
enumerable: true, // A propriedade será enumerável
configurable: false // As características da propriedade não podem ser alteradas, a propriedade não pode ser eliminada
});
console.log(obj.name); // Vai mostrar: Alice
// Tentar alterar a propriedade (será ignorado em modo estrito ou lançará erro)
obj.name = 'Bob';
console.log(obj.name); // Vai mostrar: Alice
// Tentar eliminar a propriedade (será ignorado ou lançará erro)
delete obj.name;
console.log(obj.name); // Vai mostrar: Alice
Exemplo de criação de uma propriedade com um descritor de acessórios:
// Criar um objeto com uma variável privada
const user = {
_firstName: 'John', // Variável privada por convenção
_lastName: 'Doe'
};
// Definir a propriedade 'fullName' com um descritor de acessórios
Object.defineProperty(user, 'fullName', {
get() {
// Getter: devolve o nome completo
return `${this._firstName} ${this._lastName}`;
},
set(value) {
// Setter: divide o nome completo em partes e atualiza as variáveis privadas
const parts = value.split(' ');
this._firstName = parts[0];
this._lastName = parts[1];
},
enumerable: true, // A propriedade será enumerável
configurable: true // As características da propriedade podem ser alteradas, a propriedade pode ser eliminada
});
console.log(user.fullName); // Vai mostrar: John Doe
user.fullName = 'Peter Pan';
console.log(user._firstName); // Vai mostrar: Peter
console.log(user._lastName); // Vai mostrar: Pan
console.log(user.fullName); // Vai mostrar: Peter Pan
O uso de descritores permite criar propriedades imutáveis, propriedades com cálculo preguiçoso, propriedades com controlo de acesso (getters/setters) e gerir de forma mais flexível o comportamento dos objetos.