Tutti gli articoli JS Sparks sono una collezione di guide pratiche, molto brevi, relativi ad un’unico argomento. Sono brevi, chiari a soprattutto accessibili a chiunque si stia avvicinando alla programmazione di JS.
Funzione Costruttore
Sotto un esempio che avrete già incontrato lavorando con Node.js ed Express.js.
const router = express.Router();
In questo caso assegnamo alla costante router il nuovo oggetto express.Router() che viene generato da una funzione costruttore, l’argomento che vogliamo analizzare in questo articolo.
Per dovere di cronaca, ricordiamo che il codice visualizzato crea un nuovo router, che possiamo immaginare come un set di rotte e middleware.
Ma vogliamo concentrarci sulla funzione costruttore. Questa non è altro che una funzione speciale per creare oggetti. Quando viene richiamata con l’operatore new, questa ‘istanzia’ un nuovo oggetto, cioè crea un nuovo oggetto. Questo nuovo oggetto avrà delle proprietà e dei metodi, e questi si rifanno ad un modello che è prorpio la funzione costruttore.
Sotto un semplice esempio che renderà tutto molto più chiaro.
function Persona(nome, cognome) {
// Imposta proprietà dell'oggetto con 'this'
this.nome = nome;
this.cognome = cognome;
// Definisce un metodo per l'oggetto
this.saluto = function() {
console.log(`Ciao, mi chiamo ${this.nome} ${this.cognome}`);
};
}
// Creazione di un'istanza di Persona
const persona1 = new Persona('Mario', 'Rossi');
// Chiamata al metodo dell'oggetto
persona1.saluto(); // Output: Ciao, mi chiamo Mario Rossi
Classi in JS
Dalle versioni più recenti di JS (ES6) è stato introdrodotta la sintassi delle classi, che è più chiara, e si avvicina meglio a quella di altri linguaggi come Java. Usando un termine più specifico è un synctatic sugar, cioè è un modo di costruire il codice del nostro porgramma non alterandone in alcun modo la funzionalità, ma volendo invece rendendo più facile la fruibilità da parte di un essere umano.
Questa dunque è solo una rappresentazione e internamente le classi funzionano ancora come funzioni costruttrici.
Sotto trovate l’esempio precedente usando però le classi.
class Persona {
constructor(nome, cognome) {
// Imposta proprietà dell'oggetto con 'this'
this.nome = nome;
this.cognome = cognome;
}
// Metodo della classe: in questo caso 'this.' non viene usato
saluto() {
console.log(`Ciao, mi chiamo ${this.nome} ${this.cognome}`);
}
}
// Creazione di un'istanza di Persona
const persona1 = new Persona('Mario', 'Rossi');
// Chiamata al metodo dell'oggetto
persona1.saluto(); // Output: Ciao, mi chiamo Mario Rossi
Factory Function
L’ultimo punto da chiarire è legato al perchè non usiamo new per generare l’oggetto express.Router() prendendo come modello la funzione costruttore. In questo caso si è preferito nascondere il meccanismo costruttore usando quella che viene definita una factory function. Questa non è altro che un design pattern, cioè una guida o un modello che i programmatori possono seguire per risolvere un certo tipo di problema ricorrente. In questo caso, ad esempio, l’obiettivo è quello di semplificare l’istanza, cioè la creazione, dell’oggetto Router, eliminando l’utilizzo del’operatore new.
Sotto un esempio di come modificando il codice precedente possiamo creare l’oggetto Persona sfruttando le factory function (e non usare l’operatore new).
function creaPersona(nome, cognome) {
// Crea e restituisce un nuovo oggetto Persona
return {
nome: nome,
cognome: cognome,
// Metodo saluto definito per l'oggetto creato
saluto: function() {
console.log(`Ciao, mi chiamo ${this.nome} ${this.cognome}`);
}
};
}
// Creazione di un oggetto Persona usando la factory function
const persona1 = creaPersona('Mario', 'Rossi');
persona1.saluto(); // Output: Ciao, mi chiamo Mario Rossi
Conclusione
Ma l’ora dei preamboli è finita
È l’ora che si vada ad incominciare
A tessere la trama e poi l’ordito
A svolgere, cucire e ricamare;
Che squillino le trombe signori spettatori
Inizia la commedia, che parlino gli attori.