W3docs

Getter e Setter in JavaScript

Scopri getter e setter in JavaScript: sintassi get/set, proprietà accessor vs data, validazione, proprietà calcolate e uso nelle classi.

La maggior parte delle proprietà degli object in JavaScript sono proprietà data — memorizzano semplicemente un valore. Gli object supportano però anche le proprietà accessor: proprietà supportate da funzioni che vengono eseguite ogni volta che la proprietà viene letta o scritta. Queste funzioni si chiamano getter e setter. Dall'esterno una proprietà accessor appare come una proprietà ordinaria (user.age), ma dietro le quinte è il tuo codice a decidere cosa accade realmente durante la lettura o l'assegnazione.

Questa guida tratta la sintassi get/set, le differenze tra proprietà accessor e proprietà data, i casi d'uso più comuni (validazione e valori calcolati), come getter e setter funzionano all'interno delle classi e le insidie da conoscere.

Introduzione a Getter e Setter delle Proprietà

Un getter è una funzione che viene eseguita quando si legge una proprietà; il valore restituito diventa il valore dell'accesso. Un setter è una funzione che viene eseguita quando si assegna a una proprietà; riceve il valore assegnato come unico argomento. Poiché sono funzioni, possono eseguire validazioni, calcolare un risultato al volo, registrare gli accessi o aggiornare altre proprietà — il tutto mentre il codice chiamante utilizza la normale sintassi delle proprietà.

Sintassi

All'interno di un object letterale, si definisce un getter con la parola chiave get seguita da un metodo, e un setter con la parola chiave set seguita da un metodo che accetta un parametro:

let obj = {
  get propName() {
    // getter, the code executed when obj.propName is read
  },
  set propName(value) {
    // setter, the code executed when obj.propName is written
  }
};

Puoi definire entrambi o solo uno. Una proprietà con solo un getter è in sola lettura; assegnarle un valore non produce alcun effetto in modalità non-strict e genera un TypeError in strict mode. Una proprietà con solo un setter è in sola scrittura — leggerla restituisce undefined.

Proprietà accessor vs. proprietà data

Vale la pena essere precisi riguardo al tipo di proprietà che un getter/setter crea. Una proprietà normale come width: 5 è una proprietà data con un value. Una coppia getter/setter crea invece una proprietà accessor che non ha un proprio value — ha solo le funzioni get e set. Le due forme si escludono a vicenda: un singolo descrittore di proprietà non può avere sia un value che un get/set.

Ecco perché gli esempi di validazione seguenti conservano il numero reale in un campo di appoggio separato (_age): l'accessor pubblico age ha bisogno di un posto dove memorizzare i dati, poiché non ha un proprio slot per il valore. Per esaminarlo direttamente, consulta Flag e descrittori delle proprietà.

Perché usare Getter e Setter?

Getter e setter offrono diversi vantaggi, tra cui:

  • Incapsulamento: Nascondono la rappresentazione interna dietro un'interfaccia pubblica stabile. Puoi cambiare in seguito come un valore viene memorizzato senza interrompere il codice che lo legge.
  • Validazione: Puoi rifiutare o normalizzare i valori nel setter prima che vengano memorizzati.
  • Proprietà calcolate: Un getter può ricavare il suo risultato da altre proprietà, così il valore è sempre aggiornato e non viene mai memorizzato in modo obsoleto.
  • Compatibilità con il passato: Se una proprietà che era un campo semplice necessita di logica aggiunta in seguito, puoi sostituirla con un accessor dello stesso nome — il codice chiamante non cambia.

Esempi Pratici

Vediamo alcuni esempi pratici per illustrare come getter e setter possono essere usati in scenari reali.

Esempio 1: Object Utente con Validazione dell'Età

Considera un object utente in cui vogliamo garantire che la proprietà age sia sempre entro un intervallo ragionevole. Il setter valida l'input; il getter restituisce semplicemente il campo di appoggio.

javascript— editable

Esempio 2: Creazione di Proprietà Calcolate

I getter ci permettono di creare proprietà calcolate al volo in base ad altri dati. Ogni volta che area viene letta viene ricalcolata, quindi rimane sincronizzata se width o height cambiano.

javascript— editable

Esempio 3: Definire accessor con Object.defineProperty

La sintassi letterale get/set è il modo più comune per dichiarare gli accessor, ma puoi anche aggiungerli a un object esistente — anche dopo la sua creazione — con Object.defineProperty. Ciò è utile quando il nome della proprietà è dinamico o quando vuoi controllare flag come enumerable.

javascript— editable

Buone Pratiche

Quando usi getter e setter, considera le seguenti buone pratiche per garantire che il tuo codice sia pulito, manutenibile ed efficiente:

  • Evita effetti collaterali nei Getter: I getter devono essere veloci e privi di effetti collaterali, poiché vengono spesso chiamati implicitamente dal motore o durante l'enumerazione delle proprietà.
  • Validazione: Valida sempre i dati nei setter per impedire che dati non validi o dannosi vengano memorizzati.
  • Convenzioni sui nomi: Usa un underscore iniziale (_) per i nomi delle proprietà di appoggio per indicare che sono private.
  • Serializzazione JSON: Nota che JSON.stringify() ignora i getter per impostazione predefinita. Usa una funzione replacer o una serializzazione esplicita se hai bisogno di includere valori calcolati.

Casi d'Uso Avanzati

Nomi di Proprietà Dinamici

JavaScript ES6 ha introdotto i nomi di proprietà calcolati, che possono essere combinati con getter e setter per definire dinamicamente chiavi accessor basate su variabili o espressioni.

javascript— editable

Integrazione con le Classi

Getter e setter sono molto utili anche nella programmazione basata su classi, offrendo un modo per incapsulare e controllare l'accesso alle proprietà di classe. La sintassi è identica — basta scrivere metodi get/set nel corpo della classe — e vengono collocati nel prototipo, così ogni istanza li condivide.

javascript— editable

Errori Comuni

Alcuni errori colgono gli sviluppatori di sorpresa:

  • Ricorsione infinita per un campo di appoggio errato. Se un setter per name assegna a this.name invece che a un campo separato come this._name, l'assegnazione attiva nuovamente il setter, all'infinito. Memorizza sempre il valore sotto una chiave diversa.
  • Un getter senza setter è in sola lettura. Assegnargli un valore non produce alcun effetto (o genera un errore in strict mode), il che può sembrare un bug silenzioso.
  • JSON.stringify() chiama i getter ma ignora i setter. Un getter calcolato viene serializzato (il suo valore restituito è incluso), ma non è possibile ripristinarlo tramite un setter su JSON.parse() — si ottengono solo dati semplici.
  • this dipende dal sito di chiamata. All'interno di un getter o setter, this è l'object su cui è stata effettuata l'accesso alla proprietà. Se copi l'accessor su un altro object, this cambia di conseguenza — vedi Metodi degli object e "this".

L'esempio seguente mostra la trappola della ricorsione e la sua soluzione:

javascript— editable

Conclusione

Padroneggiare i getter e setter delle proprietà è un passo fondamentale per diventare uno sviluppatore JavaScript competente. Queste funzionalità non solo migliorano la funzionalità e la sicurezza del codice, ma aprono anche la strada a codebase più leggibili e manutenibili. Seguendo le buone pratiche e gli esempi forniti in questa guida, gli sviluppatori possono sfruttare efficacemente getter e setter a loro vantaggio, portando ad applicazioni JavaScript più robuste ed efficienti.

Esercitazione

Pratica
Quali affermazioni sono vere riguardo ai getter e setter in JavaScript?
Quali affermazioni sono vere riguardo ai getter e setter in JavaScript?
Was this page helpful?