JavaScript: dichiarazioni, espressioni e arrow functions per creare utility riutilizzabili

by Anastasia P.
SHARE
JavaScript: dichiarazioni, espressioni e arrow functions per creare utility riutilizzabili
© Guida-HTML5.it

Introduzione

Quando si parla di funzioni in JavaScript, spesso ci si concentra solo sulla sintassi. In realtà, la scelta tra dichiarazioni di funzione, espressioni di funzione e arrow functions ha un impatto concreto sulla leggibilità, sulla riusabilità e sul comportamento del codice.

In questo tutorial vedremo un sotto-argomento molto pratico: come usare i tre formati di funzione per costruire utility riutilizzabili. Le utility sono piccole funzioni di supporto, ad esempio per formattare testi, validare dati, normalizzare valori o trasformare oggetti. Sono una parte fondamentale di qualsiasi progetto JavaScript ben organizzato.

L’obiettivo non è solo capire la sintassi, ma imparare quando conviene usare una dichiarazione, quando una espressione e quando una arrow function. Useremo esempi reali e un approccio orientato alla manutenzione del codice.

Codice completo

// 1) DICHIARAZIONE DI FUNZIONE
// Utile quando vuoi una funzione riutilizzabile e leggibile, accessibile anche prima della sua definizione.
function formatCurrency(amount, currency = ´EUR´) {
  return new Intl.NumberFormat(´it-IT´, {
    style: ´currency´,
    currency
  }).format(amount);
}

// 2) ESPRESSIONE DI FUNZIONE
// Molto utile quando vuoi assegnare una funzione a una variabile e trattarla come valore.
const normalizeEmail = function (email) {
  return email.trim().toLowerCase();
};

// 3) ARROW FUNCTION
// Perfetta per utility compatte, soprattutto quando il corpo è semplice e immediato.
const isValidPrice = (value) => {
  return typeof value === ´number´ && !Number.isNaN(value) && value >= 0;
};

// Utility più compatta con arrow function e ritorno implicito
const slugify = (text) =>
  text
    .trim()
    .toLowerCase()
    .replace(/s+/g, ´-´)
    .replace(/[^a-z0-9-]/g, ´´);

// Funzione dichiarata usata come orchestratore
function buildProductSummary(product) {
  const name = product.name ?? ´Prodotto senza nome´;
  const email = normalizeEmail(product.contactEmail);
  const price = isValidPrice(product.price)
    ? formatCurrency(product.price)
    : ´Prezzo non valido´;

  return {
    name,
    email,
    price,
    slug: slugify(name)
  };
}

// Esempio di input
const product = {
  name: ´  Cuffie Wireless Pro  ´,
  contactEmail: ´  [email protected] ´,
  price: 79.9
};

console.log(buildProductSummary(product));

// Esempio di validazione
console.log(isValidPrice(10));   // true
console.log(isValidPrice(-5));    // false
console.log(isValidPrice(´10´));  // false

// Esempio di riuso
console.log(formatCurrency(19.99));          // €19,99
console.log(formatCurrency(19.99, ´USD´));    // $19.99
console.log(normalizeEmail(´  [email protected] ´)); // [email protected]
console.log(slugify(´Hello World JS´));      // hello-world-js

Spiegazione

Vediamo il codice pezzo per pezzo e soprattutto il motivo per cui ogni forma di funzione è stata scelta.

1. Dichiarazione di funzione: formatCurrency

La funzione formatCurrency è stata scritta come dichiarazione:

function formatCurrency(amount, currency = ´EUR´) { ... }

Questa forma è ideale quando una funzione deve essere facilmente leggibile e richiamabile in più punti del progetto. Inoltre, le dichiarazioni sono hoistate, cioè vengono rese disponibili anche prima della loro definizione nel file. Questo può essere utile, ma va usato con attenzione per evitare confusione.

Qui la funzione usa Intl.NumberFormat, una API nativa di JavaScript, per formattare importi monetari in modo corretto. Il parametro currency ha un valore predefinito, così la funzione resta flessibile senza diventare più complessa.

2. Espressione di funzione: normalizeEmail

La funzione normalizeEmail è una funzione anonima assegnata a una variabile:

const normalizeEmail = function (email) { ... }

Questa forma è molto utile quando vuoi trattare la funzione come un valore. È comune nelle utility perché ti permette di creare funzioni modulari, facili da passare ad altre funzioni o da organizzare in oggetti e moduli.

In questo caso, la funzione normalizza un indirizzo email rimuovendo gli spazi e convertendo tutto in minuscolo. È un esempio semplice, ma molto realistico: normalizzare input utente è una pratica essenziale in qualsiasi applicazione.

3. Arrow function: isValidPrice e slugify

Le arrow functions sono perfette per utility brevi e focalizzate. Nel nostro esempio, isValidPrice verifica che il valore sia un numero valido e non negativo:

const isValidPrice = (value) => {
  return typeof value === ´number´ && !Number.isNaN(value) && value >= 0;
};

Questa funzione è leggibile, compatta e facile da testare. Inoltre, usando una const, eviti di riassegnare accidentalmente la funzione.

La funzione slugify mostra un altro vantaggio delle arrow functions: il return implicito. Quando il corpo è solo un’espressione, puoi scrivere:

const slugify = (text) =>
  text
    .trim()
    .toLowerCase()
    .replace(/s+/g, ´-´)
    .replace(/[^a-z0-9-]/g, ´´);

Questo rende il codice più compatto, senza sacrificare la chiarezza. È una scelta ottima per trasformazioni lineari di stringhe, array o valori primitivi.

4. Combinare le tre forme in una utility più grande

La funzione buildProductSummary è una dichiarazione di funzione che orchestra le altre utility:

function buildProductSummary(product) { ... }

Qui la scelta è intenzionale: una dichiarazione è adatta a una funzione “centrale” del flusso applicativo, perché comunica subito che si tratta di una funzione importante e riutilizzabile.

All’interno, la funzione:

  • usa normalizeEmail per pulire i dati di contatto,
  • usa isValidPrice per validare il prezzo,
  • usa formatCurrency per mostrare il prezzo in modo leggibile,
  • usa slugify per generare un identificatore URL-friendly dal nome del prodotto.

Questo approccio è molto utile perché separa le responsabilità: ogni funzione fa una cosa sola e la fa bene. Il risultato è un codice più facile da leggere, testare e mantenere.

Best practice

  • Usa le dichiarazioni per funzioni “di servizio” importanti e molto leggibili, soprattutto quando vuoi sfruttare l’hoisting in modo consapevole.
  • Usa le espressioni di funzione quando vuoi assegnare una funzione a una variabile, passare la funzione come valore o mantenere il codice modulare.
  • Usa le arrow functions per utility brevi, trasformazioni rapide e funzioni con logica semplice.
  • Evita le arrow functions quando hai bisogno di un proprio this dinamico o di una funzione usata come metodo in contesti particolari.
  • Preferisci funzioni piccole e specializzate: una utility dovrebbe risolvere un problema preciso, non fare troppe cose insieme.
  • Nomina bene le funzioni: un buon nome vale più di un commento lungo. Ad esempio, normalizeEmail è più chiaro di fixData.
  • Usa valori predefiniti nei parametri quando rendono la funzione più robusta, come abbiamo fatto con currency = ´EUR´.
  • Scrivi funzioni pure quando possibile: se una utility dipende solo dagli input e restituisce un output, sarà più facile da testare.

Riepilogo

Le funzioni in JavaScript non sono solo uno strumento sintattico: sono la base per organizzare il codice in modo pulito e riutilizzabile. In questo tutorial abbiamo visto un uso pratico delle tre forme principali:

  • Dichiarazioni di funzione per utility centrali e leggibili.
  • Espressioni di funzione per assegnare funzioni a variabili e modularizzare il codice.
  • Arrow functions per trasformazioni concise e funzioni compatte.

La scelta migliore dipende dal contesto. Non esiste una forma “sempre superiore”: la vera competenza sta nel saper scegliere quella più adatta al problema. In un progetto reale, combinare le tre sintassi in modo coerente ti aiuta a scrivere codice più chiaro, più mantenibile e più facile da testare.

Approfondisci con risorse ufficiali

  • MDN - Function: documentazione completa sulle funzioni in JavaScript.
  • MDN - Function declarations: approfondimento sulle dichiarazioni di funzione.
  • MDN - Function expressions: guida alle espressioni di funzione.
  • MDN - Arrow functions: spiegazione dettagliata della sintassi arrow e del comportamento di this.
  • MDN - Intl.NumberFormat: utile per formattare numeri e valute in modo corretto.

SHARE