Oggi esploriamo due concetti chiave nel mondo della programmazione, specialmente della programmazione in JavaScript: le funzioni di callback e le Higher Order Function! Sono concetti molto legati fra loro, ma ho notato che spesso si tende a conoscere il primo e a spaventarsi e correre via quando viene nominato il secondo… state già scappando? Dai che è facile, vediamoli assieme.

Cos’è una callback

Se conoscete abbastanza bene JavaScript, sapete di sicuro che le funzion…

No, calma. Voglio esserne sicuro. Ecco cosa dovete avere bene a mente:

In JavaScript, le funzioni sono oggetti

Facciamo qualche esperimento. Vediamo qual è il tipo di una funzione…

function sayHi() {
  console.log('Hi');
}

console.log(typeof sayHi); // Function [occhio, è un OGGETTO di tipo Function!]

Vediamo se possiamo aggiungerci delle proprietà (è solo una prova, non fatelo!)

sayHi.description = 'Says hi to the console';

console.log(sayHi.description); // 'Says hi to the console'

Funziona. Ora vediamo se possiamo assegnarle ad una variabile…

var sayHi = function() {
  console.log('Hi');
}

sayHi(); // 'Hi'

Pare si possa! E se la riassegno?

var test = sayHi;

test(); // 'Hi'

Funziona anche così. Attenzione a quest’ultimo esempio perché chiamando test() stiamo a tutti gli effetti chiamando sayHi(), non una funzione uguale, proprio lei! Questo perché le funzioni (e gli oggetti) non sono primitive, non vengono assegnate per valore!

Le funzioni sono First-class citizen

Cos’è un First-class citizen? Traducendolo al volo non ci dà un grosso aiuto: cittadino di prima classe. Ma cosa vuol dire?

Prendiamo la definizione da Wikipedia (o da qualsiasi libro di testo sull’argomento) ed è tutto più chiaro:

Un’entità che può essere costruita a run-time, passata come parametro, ritornata da una subroutine [ovvero una funzione], o assegnata ad una variabile.

https://en.wiktionary.org/wiki/first-class_object

Beh, in parte già ci siamo: sappiamo che una funzione può essere assegnata ad una variabile e sappiamo che può essere costruita a run-time, ma… passata come parametro? Ritornata da una funzione? Vediamo come.

Funzioni di callback

Vediamo se possiamo testare la nostra prima perplessità, ovvero passare una funzione come parametro:

function sayHi() {
  console.log('Hi');
}

function sayYourNameAnd(name, callback) {
  console.log('My name is ' + name);
  callback();
}

console.log(sayYourNameAnd('Michele', sayHi)); // 'My name is Michele', 'Hi'

Pare si possa! Abbiamo passato la funzione sayHi ad un’altra funzione (attenzione, non abbiamo passato sayHi() con le parentesi, quello è il risultato della funzione!) e dall’interno dell’altra funzione l’abbiamo richiamata. Bello, no?

Bene, abbiamo appena scoperto che sayHi, in questo caso, è una funzione di callback. Infatti non è che una funzione o è di callback o non lo è, semplicemente può essere usata come tale: callback significa letteralmente “richiamare”, ed è quello che è successo. Abbiamo passato una funzione come parametro, e l’altra funzione l’ha poi richiamata per i fatti suoi!

Volete altri esempi? Credo ne conosciate già più di uno, ecco il più famoso:

// Il secondo parametro è una funzione di callback!
document.addEventListener('click', function() {
  console.log('Clicked!');
});

Abbiamo quindi verificato che possiamo passare le funzioni come parametro. Ma che vengano ritornate da un’altra funzione?

Funzioni che ritornano funzioni

Proviamo a scriverne una? Una semplice.

function prepareGreeting(name) {

  return function() { console.log('Hi, ' + name); }
}

var greeting = prepareGreeting('Michele'); // Nulla viene stampato

console.log(greeting()); // 'Hi, Michele'

Bellissimo, no? In pratica, questo pattern ci permette di personalizzare una funzione, che viene prima preparata e poi, in caso, eseguita. Nel nostro esempio, prima abbiamo detto il nostro nome, poi abbiamo chiesto di stampare un saluto in console. La funzione di ritorno, infatti, non poteva funzionare senza il nostro nome.

Possiamo anche fare uno step successivo e rendere la funzione interna riutilizzabile, spostandola fuori dal suo scope:

function sayHi(name) {
  console.log('Hi, ' + name);
}

function prepareGreeting(name) {

  return sayHi.bind(null, name);
}

Come funziona? La faccio breve, perché serve un altro articolo per spiegarla al meglio: con bind, prepariamo una funzione (senza chiamarla), e rendiamo prestabilito che null sarà il nuovo contesto in cui sarà chiamata la funzione (al posto del suo this), mentre i parametri successivi prenderanno il posto dei parametri originali. Se non vi è chiaro non importa, era solo un piccolo esempio.

Bene, ora che sappiamo che una funzione può ritornare una funzione, abbiamo verificato che le funzioni in JavaScript sono First-class citizen! E le Higher Order Function?

Higher Order Functions

Beh… le avete appena imparate. Una Higher Order Function è una funzione che accetta un’altra funzione come parametro, o che ritorna un’altra funzione. Praticamente i nostri due capitoli precedenti. Piaciuto lo scherzetto? Devo pur variare i miei articoli in qualche modo… 😀

Conclusioni

A parte gli scherzi adesso. Le funzioni di callback e le Higher Order Function sono due pratiche usatissime in JavaScript, e sono così usate perché sono molto potenti. Ci permettono di comporre codice in maniera dichiarativa piuttosto che imperativa. Se non esistessero, non avremmo strumenti come map, filter e reduce, ad esempio. Per non parlare di altri strumenti presenti in librerie e framework che ne fanno largo uso, come gli Higher Order Components in React o gli Higher Order Observable in RxJS. Come dite? Cosa sono? Sono tutte funzioni, naturalmente: stiamo parlando di JavaScript! 😉

Ti è piaciuto l’articolo? Condividilo!

Rilasciare risorse gratuite non è facile: un sacco di tempo vola fra la ricerca dell’idea, la stesura, la preparazione di codice funzionante e la revisione. Se ti piace ciò che facciamo, condividi l’articolo: nel peggiore dei casi ti daranno del secchione!

Ti interesserà anche…

Componenti stateless, stateful, dumb e smart

Qualsiasi sia la libreria o il framework front-end che utilizziate, se è basato su un’architettura a Componenti (come Angular, React, Vue…) sicuramente vi sarete imbattuti in queste terminologie: stateless, stateful,…

Iscriviti alla nostra newsletter!

Rimani aggiornato per quando rilasceremo nuovi articoli, nuovi corsinuove promozioni e nuove risorse gratuite. Ti promettiamo che useremo la tua email con prudenza, e non la condivideremo con nessuno senza il tuo consenso!

Abbiamo a cuore la tua privacy. Niente spam. Leggi la nostra privacy policy qui.

Menu