JavaScript: funzioni dichiarate, espresse e arrow functions nelle classi e nei metodi

by Anastasia P.
SHARE
JavaScript: funzioni dichiarate, espresse e arrow functions nelle classi e nei metodi
© Guida-HTML5.it

Introduzione

Quando si studiano le funzioni in JavaScript, spesso ci si concentra sulla sintassi di base: dichiarazioni, espressioni e arrow functions. Un sotto-argomento molto utile, però, è capire come queste forme di funzione si comportano dentro le classi e nei metodi degli oggetti.

Questo tema è pratico perché, nello sviluppo reale, gran parte del codice JavaScript moderno lavora con classi, istanze, metodi e callback interne. La scelta tra una funzione dichiarata, una funzione espressa o una arrow function può cambiare il comportamento di this, la leggibilità del codice e la manutenibilità del progetto.

In questo tutorial vedremo come usare correttamente le tre forme di funzione nei metodi di classe, quando preferire una soluzione rispetto a un’altra e quali errori evitare.

Codice completo

// Esempio: gestione di un carrello con classe JavaScript

class Carrello {
  constructor(nomeCliente) {
    this.nomeCliente = nomeCliente;
    this.prodotti = [];
  }

  // Metodo di classe: funzione "normale" definita nella classe
  aggiungiProdotto(nome, prezzo) {
    this.prodotti.push({ nome, prezzo });
  }

  // Metodo che usa una funzione espressa come callback
  calcolaTotaleConCallback() {
    return this.prodotti.reduce(function (totale, prodotto) {
      return totale + prodotto.prezzo;
    }, 0);
  }

  // Metodo che usa una arrow function come callback
  calcolaTotaleConArrow() {
    return this.prodotti.reduce((totale, prodotto) => {
      return totale + prodotto.prezzo;
    }, 0);
  }

  // Metodo che restituisce una funzione dichiarata
  creaMessaggio() {
    function formattaMessaggio(cliente, totale) {
      return `Cliente: ${cliente} | Totale: €${totale}`;
    }

    const totale = this.calcolaTotaleConArrow();
    return formattaMessaggio(this.nomeCliente, totale);
  }

  // Metodo che usa una arrow function per mantenere il contesto di this
  stampaRiepilogo() {
    setTimeout(() => {
      console.log(`Riepilogo per ${this.nomeCliente}`);
      console.log(`Numero prodotti: ${this.prodotti.length}`);
      console.log(`Totale: €${this.calcolaTotaleConArrow()}`);
    }, 1000);
  }
}

// Uso della classe
const carrello = new Carrello("Luca");

carrello.aggiungiProdotto("Tastiera", 49.99);
carrello.aggiungiProdotto("Mouse", 24.5);
carrello.aggiungiProdotto("Monitor", 199.9);

console.log(carrello.calcolaTotaleConCallback()); // 274.39
console.log(carrello.creaMessaggio()); // Cliente: Luca | Totale: €274.39
carrello.stampaRiepilogo();

Spiegazione

Nel codice sopra abbiamo tre modi diversi di lavorare con le funzioni.

1. Metodo di classe

Il metodo aggiungiProdotto è definito direttamente nella classe. Anche se sintatticamente sembra diverso da una funzione classica, in realtà è un metodo, cioè una funzione associata alla classe. Questo è il modo più comune per definire comportamenti dell’oggetto.

2. Funzione espressa come callback

Nel metodo calcolaTotaleConCallback usiamo reduce con una funzione espressa tradizionale:

  • è utile quando vuoi una callback autonoma;
  • ha un proprio contesto this;
  • va bene se non devi accedere a proprietà dell’istanza.

In questo caso non serve this, quindi la funzione tradizionale è perfetta.

3. Arrow function come callback

Nel metodo calcolaTotaleConArrow la callback di reduce è una arrow function. Qui il vantaggio principale è la sintassi più compatta. Le arrow function sono molto comode nelle operazioni su array, nei cicli funzionali e nelle callback brevi.

Se la callback deve usare il contesto esterno, la arrow function è spesso la scelta migliore perché non crea un proprio this.

4. Funzione dichiarata dentro un metodo

Nel metodo creaMessaggio abbiamo una funzione dichiarata locale, formattaMessaggio. Questa funzione è utile quando vuoi separare una piccola logica interna dal resto del metodo. È una soluzione leggibile se la funzione:

  • è usata solo in quel punto;
  • non dipende dal contesto dell’istanza;
  • ha un compito chiaro e limitato.

5. Arrow function per preservare this

Il caso più importante è stampaRiepilogo. Qui usiamo setTimeout con una arrow function. Se avessimo usato una funzione tradizionale, il valore di this sarebbe cambiato e non punterebbe più all’istanza di Carrello.

Con la arrow function, invece, this viene ereditato dal contesto esterno, cioè dal metodo stampaRiepilogo. Questo è uno dei motivi per cui le arrow functions sono così diffuse nelle classi e nelle callback asincrone.

Best practice

  • Usa i metodi di classe per il comportamento principale dell’oggetto.
  • Usa funzioni dichiarate quando vuoi creare helper locali leggibili e riutilizzabili dentro un metodo.
  • Usa arrow functions nelle callback quando ti serve mantenere il contesto di this.
  • Evita arrow functions come metodi di classe se devi accedere dinamicamente a this in modo tradizionale o se vuoi sfruttare il prototipo in modo più efficiente.
  • Non usare function tradizionali nelle callback se non sei sicuro del contesto: potresti introdurre bug difficili da individuare.
  • Preferisci funzioni brevi e nominate quando la logica cresce: il codice sarà più facile da testare e mantenere.

Un errore comune è pensare che le arrow functions siano sempre migliori. In realtà, sono ottime per molte callback, ma non sostituiscono completamente le funzioni tradizionali. La scelta dipende dal contesto e dall’obiettivo.

Riepilogo

Le funzioni in JavaScript non sono tutte uguali, soprattutto quando entrano in gioco le classi.

  • Dichiarazioni di funzione: utili per helper locali e codice leggibile.
  • Espressioni di funzione: ottime nelle callback tradizionali.
  • Arrow functions: ideali per callback concise e per mantenere il valore di this.

Capire come queste forme si comportano nei metodi di classe ti aiuta a scrivere codice più robusto, più chiaro e meno soggetto a errori di contesto.

Approfondisci con risorse ufficiali

  • MDN Web Docs - Functions: documentazione completa sulle funzioni JavaScript.
  • MDN Web Docs - Arrow functions: guida dettagliata sulle arrow functions e sul comportamento di this.
  • MDN Web Docs - Classes: riferimento ufficiale per le classi in JavaScript.
  • ECMAScript Language Specification: specifica ufficiale del linguaggio per chi vuole approfondire il comportamento interno delle funzioni.

SHARE