Sobes.tech
Middle+

Cosa sai sugli descrittori?

sobes.tech AI

Risposta dell'AI

I descrittori in JavaScript sono oggetti che descrivono le proprietà di una proprietà di un oggetto, come il suo valore (value), la possibilità di scrittura (writable), la possibilità di enumerazione (enumerable) e la possibilità di configurazione (configurable). Esistono anche descrittori con getter e setter.

Ci sono due tipi di descrittori:

  • Descrittori di dati: Contengono il valore della proprietà.

    • value: Il valore della proprietà. Può essere di qualsiasi tipo di dato valido.
    • writable: Un valore booleano. Se true, il valore della proprietà può essere modificato (obj.prop = newValue). Per impostazione predefinita, è false per le proprietà di accesso e true per le proprietà di dati create tramite assegnazione normale.
    • enumerable: Un valore booleano. Se true, la proprietà sarà visibile durante l'iterazione sulle proprietà dell'oggetto (ad esempio, in un ciclo for...in o usando Object.keys()). Per impostazione predefinita, è false per le proprietà aggiunte con Object.defineProperty e true per quelle create tramite assegnazione normale.
    • configurable: Un valore booleano. Se true, le caratteristiche del descrittore (eccetto value e writable quando cambiano da dati a accessori) possono essere modificate, e la proprietà può essere eliminata. Per impostazione predefinita, è false per le proprietà aggiunte con Object.defineProperty (eccetto value) e true per quelle create tramite assegnazione normale. Una volta configurato come non configurabile, non può essere modificato di nuovo. Puoi diminuire la writable da true a false, ma non viceversa su un getter/setter non configurabile.
  • Descrittori di accessori: Definiscono funzioni che vengono chiamate al recupero (getter) o impostazione (setter) del valore della proprietà.

    • get: Funzione chiamata durante la lettura della proprietà. Il risultato di questa funzione diventa il valore della proprietà. Non accetta argomenti.
    • set: Funzione chiamata durante la scrittura nella proprietà. Accetta un argomento, che è il nuovo valore da impostare.
    • enumerable: Un valore booleano (simile ai descrittori di dati).
    • configurable: Un valore booleano (simile ai descrittori di dati).

I descrittori non devono essere mescolati: una proprietà ha o value e writable, o get e set.

I descrittori vengono usati per gestire le proprietà di un oggetto a un livello più basso rispetto all'assegnazione normale, in particolare tramite i metodi Object.defineProperty(), Object.defineProperties(), Object.getOwnPropertyDescriptor(), Object.getOwnPropertyDescriptors(), Object.create().

Esempio di creazione di una proprietà con un descrittore di dati:

// Creiamo un oggetto vuoto
const obj = {};

// Definiamo la proprietà 'name' con un descrittore di dati
Object.defineProperty(obj, 'name', {
  value: 'Alice',
  writable: false, // La proprietà non può essere modificata
  enumerable: true, // La proprietà sarà enumerabile
  configurable: false // Le caratteristiche della proprietà non possono essere modificate, la proprietà non può essere eliminata
});

console.log(obj.name); // Mostrerà: Alice

// Tentativo di modificare la proprietà (sarà ignorato in modalità strict o lancerà errore)
obj.name = 'Bob';
console.log(obj.name); // Mostrerà: Alice

// Tentativo di eliminare la proprietà (sarà ignorato o lancerà errore)
delete obj.name;
console.log(obj.name); // Mostrerà: Alice

Esempio di creazione di una proprietà con un descrittore di accessori:

// Creiamo un oggetto con una variabile privata
const user = {
  _firstName: 'John', // Variabile privata per convenzione
  _lastName: 'Doe'
};

// Definiamo la proprietà 'fullName' con un descrittore di accessori
Object.defineProperty(user, 'fullName', {
  get() {
    // Getter: restituisce il nome completo
    return `${this._firstName} ${this._lastName}`;
  },
  set(value) {
    // Setter: divide il nome completo in parti e aggiorna le variabili private
    const parts = value.split(' ');
    this._firstName = parts[0];
    this._lastName = parts[1];
  },
  enumerable: true, // La proprietà sarà enumerabile
  configurable: true // Le caratteristiche della proprietà possono essere modificate, la proprietà può essere eliminata
});

console.log(user.fullName); // Mostrerà: John Doe

user.fullName = 'Peter Pan';
console.log(user._firstName); // Mostrerà: Peter
console.log(user._lastName); // Mostrerà: Pan
console.log(user.fullName); // Mostrerà: Peter Pan

L'uso dei descrittori permette di creare proprietà immutabili, proprietà con calcolo pigro, proprietà con controllo di accesso (getter/setter) e di gestire più flessibilmente il comportamento degli oggetti.