Sintassi delle Classi in JavaScript
In JavaScript, le classi forniscono una sintassi per la programmazione orientata agli oggetti più tradizionale, offrendo struttura e chiarezza.
Introduzione alla Sintassi delle Classi JavaScript
Una classe è un modello per creare oggetti che condividono la stessa struttura e lo stesso comportamento. Invece di scrivere manualmente il solito boilerplate con funzione costruttore più prototipo, si descrive l'oggetto una volta sola e si creano tutte le istanze necessarie. Le classi sono state introdotte in ECMAScript 2015 (ES6) e sono diventate il modo standard per modellare il codice orientato agli oggetti in JavaScript.
Questo capitolo tratta gli elementi essenziali: come dichiarare una classe, cosa fa il constructor, come aggiungere metodi, getter/setter e campi pubblici, la differenza tra dichiarazioni di classe ed espressioni di classe, e due aspetti che confondono spesso gli sviluppatori — le classi sono funzioni sotto il cofano e non sono soggette all'hoisting come le funzioni normali.
Definire una Classe
Una classe si dichiara con la parola chiave class, seguita da un nome e da un corpo tra parentesi graffe:
class MyClass {
// class body
}Per convenzione i nomi delle classi usano il PascalCase (Rectangle, UserAccount). Il corpo contiene metodi, getter/setter e campi — ma attenzione: a differenza degli object literal, i membri non sono separati da virgole.
Il Constructor
Il constructor è un metodo speciale che viene eseguito automaticamente quando si crea un'istanza con new. Il suo compito è ricevere argomenti e inizializzare le proprietà del nuovo oggetto tramite this:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}Una classe può avere al massimo un constructor. Se lo si omette, JavaScript ne fornisce automaticamente uno vuoto.
Creare un'Istanza
Si usa la parola chiave new per creare un'istanza. new crea un nuovo object, lo associa a this, esegue il constructor e restituisce l'object:
Metodi di Classe
I metodi dichiarati nel corpo vengono aggiunti al prototipo della classe, quindi ogni istanza condivide una sola copia anziché averne una propria. All'interno di un metodo, this si riferisce all'istanza su cui il metodo è stato chiamato:
I metodi di classe sono non enumerabili, il che significa che non compariranno in un ciclo for...in né in Object.keys() — un'altra differenza tra le classi e i plain object, dove i metodi aggiunti sono enumerabili.
Getter e Setter
Un getter consente di esporre un valore calcolato come se fosse una proprietà; un setter consente di intercettare un'assegnazione. Si aggiunge il prefisso get o set a un metodo:
Getter e setter sono ideali per la validazione o i valori derivati. Consulta Property getters and setters per un approfondimento.
Campi Pubblici di Classe
È possibile dichiarare e inizializzare le proprietà di istanza direttamente nel corpo della classe, senza doverle scrivere all'interno del constructor. Questi sono i campi pubblici di classe:
I campi vengono assegnati a ciascuna istanza (non al prototipo) prima che il corpo del constructor venga eseguito. Per i campi che devono essere nascosti al codice esterno, si usano i campi privati (prefisso #) — trattati in Private and protected properties and methods.
Metodi Static
Un metodo static appartiene alla classe stessa, non alle sue istanze. I membri static sono utili per funzioni di utilità o factory function correlate alla classe ma che non richiedono un'istanza specifica:
Le classi supportano anche campi e proprietà static. Per il quadro completo, consulta Static properties and methods.
Espressioni di Classe
Proprio come le funzioni, le classi possono essere definite come espressioni e assegnate a una variabile. Le espressioni di classe possono essere anonime o con nome:
Questo è utile quando si ha bisogno di creare una classe in modo condizionale, passarla come argomento o restituirla da una funzione.
Le Classi Sono Funzioni Sotto il Cofano
Una classe è in realtà un tipo speciale di funzione. La sintassi class è in gran parte zucchero sintattico sul più vecchio pattern costruttore-funzione-più-prototipo, con alcune garanzie aggiuntive:
Le garanzie aggiuntive includono: il corpo viene sempre eseguito in strict mode, i metodi sono non enumerabili, e un constructor di classe non può essere chiamato senza new (farlo genera un TypeError).
Le Classi Non Sono Soggette all'Hoisting
Le dichiarazioni di funzione sono soggette all'hoisting — è possibile chiamarle prima che appaiano nel codice. Le dichiarazioni di classe non sono utilizzabili prima di essere definite. Vengono sollevate solo nel nome ma rimangono nella "temporal dead zone", quindi accedervi prematuramente genera un ReferenceError:
Dichiara sempre una classe prima di utilizzarla.
Riepilogo
Le classi JavaScript conferiscono al codice orientato agli oggetti una struttura chiara e prevedibile. In questo capitolo hai visto come dichiarare una classe, scrivere un constructor, aggiungere metodi di prototipo, getter/setter, campi pubblici e metodi static, oltre alle espressioni di classe. Ricorda i due fatti fondamentali: una classe è una funzione sotto il cofano il cui corpo viene eseguito in strict mode e non può essere chiamata senza new, e le dichiarazioni di classe non sono soggette all'hoisting.
Da qui, i passi naturali successivi sono estendere le classi con Class inheritance, raggruppare le utilità condivise con Static properties and methods, e nascondere lo stato interno con Private and protected properties and methods.