Essere al passo con i tempi con un linguaggio in continua evoluzione come JavaScript è incredibilmente importante per la carriera di qualsiasi sviluppatore, ed è per questo semplice motivo che abbiamo deciso di pubblicare questo articolo e aiutarti in questo importante compito.
Ti è mai capitato di seguire un tutorial su qualche pagina web per poi scoprire, dopo aver speso delle ore a comprendere i temi trattati e fare esperimenti, che il codice che hai scritto è vecchio di diversi anni?!?
Se ti è successo sappi che capisco bene la tua frustrazione perché anche io mi sono trovato diverse volte in questa situazione, ecco perché adesso se cerco qualche tutorial in rete investo quasi più tempo nell’accertarmi che le informazioni che contiene siano aggiornate.
Al tempo stesso devo farti una confessione, ci sono diversi punti di vista quando si parla di Underscore.js perché per alcuni questa libreria può risultare datata, mentre per altri viene ritenuta ancora molto utile.
Chi ha ragione?
In tutta onestà credo che siano i primi quelli che hanno veramente ragione, in fin dei conti JavaScript con le novità introdotte nella sintassi ES2015 (conosciuta anche come ES6) ha aggiunto molte delle funzionalità di questa libreria all’interno delle sue specifiche; al tempo stesso ho deciso comunque di parlare di questa libreria per due motivi principali:
- questa libreria è inclusa all’interno di WordPress da diversi anni ed è molto probabile che tu ti trovi a mettere le mani su qualche plugin o tema che ne fa uso, per questo devi essere pronto a sapere come utilizzarla;
- con la stesura di questo articolo mi apro le porte a un successivo che pubblicheremo dove parlerà proprio delle differenze tra Underscore.js e la nuova sintassi di JavaScript.
Leggendo il secondo punto potresti pensare: non facevi prima a scrivere direttamente l’articolo di confronto?
Se il mio unico scopo fosse fare prima, avrei fatto sicuramente prima dato che non mi sarei trovato a scrivere un articolo aggiuntivo, ma quello che mi chiedo ogni volta che le mie mani toccano la tastiera è: sto facendo un buon lavoro?
Se non affrontiamo un passo alla volta sicuramente lascerei qualcosa da parte e non starei facendo bene il mio lavoro ed è per questo motivo che ho deciso di affrontare comunque questo argomento.
Sai tutto quello che c’è da sapere su Underscore.js e non vedi l’ora di leggere l’articolo di confronto con ES2015? Allora ti consiglio proprio di iscriverti alla nostra newsletter e sapere per primo quando verrà pubblicato.
In fin dei conti che cosa è Underscore.js?!?
Adesso che ritengo di aver messo in luce le varie motivazioni che mi hanno spinto a scrivere questo articolo penso che sia giunto proprio il momento di scrivere la risposta a questa domanda: che cosa fa Underscore.js?
Proprio come una qualsiasi altra libreria JavaScript anche questa mira a semplificarci la vita da sviluppatori mettendoci a disposizione delle nuove sintassi e costrutti che ci permettono di scrivere un codice più pulito e facile da leggere.
Se vai a leggere quanto scritto sulla homepage del progetto scoprirai che:
Underscore.js è una libreria che offre un gran numero di funzionalità create per aiutare gli sviluppatori JavaScript senza la necessità di estendere gli oggetti built-in di questo linguaggio. Funziona sia con jQuery che con Backbone.
Come puoi vedere l’interesse di Underscore.js non è tanto quello di modificare il nostro approccio allo sviluppo in JavaScript, un po’ come ha fatto jQuery negli ultimi dieci anni, ma piuttosto quello di aiutarci nei compiti più ripetitivi che possiamo incontrare durante il nostro lavoro.
Per comprendere al meglio le utility che mette a disposizione questa libreria c’è bisogno di un bell’esempio pratico, prendiamo spunto tra uno di quelli più famosi per vedere come potrà aiutarci.
Diciamo che abbiamo un array di valori che possono variare da 0 a 99. Ci interessa avere una raccolta dei valori che superano 85, se abbiamo a disposizione soltanto JavaScript vanilla potremmo scrivere qualcosa del genere:
var punteggi = [42, 99, 34, 43, 90, 86, 67, 79, 85, 96], sopraLimite = [], limite = 85; for ( var i = 0; i <= punteggi.length; i++ ){ if ( punteggi[i] > limite ){ sopraLimite.push( punteggi[i] ); } } console.log( sopraLimite );
Il codice che vediamo qua sopra è un semplice script JavaScript che fa quanto descritto, crea un array che conterrà soltanto i valori che superano il limite di 85. La logica è semplice e anche il codice, ma grazie a Underscore.js potremmo scrivere qualcosa di ancora più ridotto:
var punteggi = [42, 99, 34, 43, 90, 86, 67, 79, 85, 96], sopraLimite = [], limite = 85; sopraLimite = _.select( punteggi, function( pun ){ return pun > limite; } ); console.log(sopraLimite);
Sicuramente in questo caso il codice scritto in Underscore.js ci ha permesso di risparmiare soltanto qualche riga di codice ed evitare di scrivere sia il ciclo for
che if
, ma c’è ancora molto più da scoprire in questa piccola libreria e come ti annunciavo precedentemente conoscere la sua sintassi ci aiuterà a scrivere codice JavaScript moderno.
Come iniziare a lavorare con Underscore.js
Iniziare a lavorare con questa libreria è semplicissimo, basta scaricarla da questo indirizzo e collegarla all’interno del nostro progetto con un classico <script>
, proprio come avviene già per il codice scritto in jQuery lo script che utilizzerà la sua sintassi dovrà essere dichiarato successivamente.
Per gli scopi di questo articolo abbiamo creato questa semplicissima pagina HTML:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Esperimenti con Underscore.js</title> </head> <body> <script type="text/javascript" src="js/underscore.js"></script> <script src="js/und-test.js" charset="utf-8"></script> </body> </html>
Come puoi notare tu stesso non c’è assolutamente niente di strano in questa pagina, tutto quello che abbiamo fatto è stato richiamare la libreria e un file all’interno del quale scriveremo i vari esperimenti che faremo in questo articolo.
Mi farebbe molto piacere che tu provassi assieme a me esempio dopo esempio quello che è in grado di fare questa libreria perché riesce veramente a semplificare molto la nostra vita e porta oltre 100 funzioni che ci possono aiutare nel nostro quotidiano lavoro.
Se vuoi la strada facile, al posto di scaricare Underscore.js e creare il tuo progetto di esempio puoi sempre scaricare tutto dal nostro repository. Se però vuoi veramente imparare qualcosa ricordati di lanciare il comando git commit 885bd22
in questo modo potrai iniziare a lavorare sul primo commit del repository e potrai passo passo.
Adesso che abbiamo fatto i passaggi di configurazione necessari andiamo a conoscere più da vicino questa libreria.
Se lavori con WordPress collegare questa libreria è ancora più semplice perché tutto quello che dovrai fare è aggiungere wp_enqueue_script( ‘underscore’ ); e il gioco è fatto. La piattaforma penserà a caricare la libreria inclusa e tu sarai libero di dichiarare il tuo nuovo file indicando come dipendenza wp_enqueue_script( ‘tuo-script’, ‘/percorso/tuo_script.js’, array( ‘underscore’ ) );.
Come Underscore.js organizza le funzioni
Poco fa ti ho detto che con questa libreria avremo molte funzioni, ma a essere onesti ne abbiamo più di 100 in grado di facilitare il nostro lavoro, per nostra fortuna queste sono raggruppate in cinque categorie ben distinte:
- Collection – tutte le funzioni che lavorano con array o oggetti si trovano in questa categoria, precedentemente abbiamo visto
select
che appartiene appunto a questa; - Array – ovviamente non tutto può lavorare per tipi di dati distinti, per questo motivo abbiamo una categoria pensata esclusivamente per gli array;
- Objects – e questa categoria interamente dedicata agli oggetti che ci permetterà di clonarli, estenderli e manipolarli più facilmente;
- Functions – per quanto strana possa sembrare Underscore.js ha un’intera categoria di funzioni che ci permettono di lavorare sulle… funzioni 🙂
- Utility – se per qualche motivo non ci sono bastate le precedenti categorie ne abbiamo anche una che raccoglie le funzioni che ci permettono di avere una spinta in più.
Ovviamente 100 funzioni suddivise in 5 categorie sono veramente molte da poter analizzare all’interno di un singolo articolo, per questo motivo ho deciso di fare una scelta e presentarti soltanto quelle che ritengo più interessanti e utili. Vedremo in un prossimo articolo un’altra motivazione che mi ha spinto a presentarti le successive soluzioni, ma non corriamo troppo.
Iniziamo ora con l’approfondimento di ogni categoria per scoprire le funzioni che ritengo più interessanti e utili al nostro scopo.
Collection
Abbiamo detto che in questa troviamo una serie di funzioni che possono essere usate sia per lavorare con gli array che con gli oggetti, vediamo di scoprire le più interessanti.
Each
Sono sicuro che in qualsiasi progetto sul quale hai lavorato ti sei trovato di fronte alla necessità di dover estrapolare i valori presenti in un array, questo ti ha spinto a dover scrivere un codice del genere:
var linguaggi = [ 'PHP', 'JavaScript', 'CSS', 'HTML', 'Ruby', 'Go' ]; for( var i = 0; i < linguaggi.length; i++ ){ console.log( 'Linguaggio: ' + linguaggi[i] ); }
Il codice che stiamo usando in questo blocco di codice è relativamente semplice e le soluzioni che ti presenterò possono sembrare quasi ovvie, allo stesso modo c’è la possibilità di risparmiare qualche carattere e di evitare la scrittura del ciclo for
se ci affidiamo alla potenza di Underscore.js:
var linguaggi = [ 'PHP', 'JavaScript', 'CSS', 'HTML', 'Ruby', 'Go' ]; _.each( linguaggi, function( linguaggio, index, linguaggi ) { console.log( 'Linguaggio: ' + linguaggio + ' con indice(' + index + ')' ); });
Come puoi vedere da questo esempio la lunghezza del nostro codice non è assolutamente cambiata ma per uno che sbaglia sempre a scrivere length
(non mi entra proprio in testa), devo ammettere che la situazione è migliorata.
each()
chiede principalmente due parametri:
- il primo è l’array che dovrà ciclare
- mentre il secondo rappresenta una funzione di callback
Quando usiamo _.each() presta sempre molta attenzione alla funzione di callback che deve essere presente come secondo parametro e quindi deve vivere all’interno delle parentesi tonde.
Lavorare in JavaScript ci ha portato a conoscere molto bene le funzioni di callback e quindi non è mia intenzione andare a descriverle in questo articolo, quello che mi interessa invece presentare sono i parametri usati che onestamente trovo molto interessanti:
- con il primo parametro è possibile inserire il nome della variabile che conterrà il valore per la specifica iterazione;
- il secondo permette di conoscere l’indice consultato nel momento dell’iterazione;
- mentre con il terzo dobbiamo specificare nuovamente l’array per il quale desideriamo conoscere i valori contenuti.
Se devo essere onesto con te, l’unica cosa che mi disturba un po’ è proprio il fatto di dover dichiarare una seconda volta l’array all’interno del quale vogliamo ciclare. Ma in fin dei conti poco importa perché con questa sintassi è veramente un gioco da ragazzi sapere quali sono i valori contenuti all’interno dei miei array 🙂
Pluck
Incontriamo una nuova funzione che ci mostra ancora più chiaramente l’utilità di questa libreria. Diciamo per esempio che nel tuo programma hai avuto la necessità di creare un array che contiene una serie di oggetti, questi hanno delle proprietà per le quali ti interessa conoscere il valore.
Per andare sul pratico qua sotto trovi la dichiarazione di questo tipo di array dove specifichiamo un linguaggio di programmazione e il suo relativo framework attraverso vari oggetti JavaScrippt:
var langFramework = [ { linguaggio: 'PHP', framework: 'Zend' }, { linguaggio: 'PHP', framework: 'Laravel' }, { linguaggio: 'Python', framework: 'Django' }, { linguaggio: 'Ruby', framework: 'Ruby on Rails' }, { linguaggio: 'JavaScript', framework: 'jQuery' }, { linguaggio: 'JavaScript', framework: 'AngularJs' } ];
Da questo array tutto quello che mi interessa ottenere sono i nomi dei framework, scrivendo in JavaScript avrei dovuto utilizzare la seguente sintassi:
var frameworks = []; for (var i = 0; i < langFramework.length; i++) { frameworks.push( langFramework[i]['framework'] ); } console.log( frameworks );
Come già successo precedentemente, creiamo un ciclo for
e lo utilizziamo (questa volta) per popolare l’array frameworks
grazie alla funzione push()
. Prima di passare all’esempio scritto in Underscore.js vorrei farti prestare attenzione alla complessità che abbiamo nella dichiarazione del valore, noti quante parentesi quade sono utilizzate? La possibilità di fare un errore è dietro l’angolo.
Mentre con questa libreria i nostri problemi sono molto più semplificati:
var framework = _.pluck( langFramework, 'framework' ); console.log( framework );
Ecco che adesso questa libreria inizia a dimostrare la sua vera utilità, non credi?
In fin dei conti ci siamo salvati da tutti i problemi che richiedono la stesura di un ciclo for
e dalla sintassi che ci obbliga a utilizzare. Se ancora non l’hai notato abbiamo ottenuto quello che desideravamo in una singola riga di codice.
Anche la sintassi non è affatto male, la funzione pluck()
richiede soltanto due parametri, l’array dal quale estrapolare i valori e la chiave di nostro interesse.
Map
Ed eccoci all’ultima funzione che ti voglio presentare per quanto riguarda la categoria Collection e che ha fatto riscuotere molto successo a questa libreria, la funzione map()
.
Diciamo che per esempio abbiamo un array, o un oggetto, per il quale vogliamo modificare tutti i suoi valori. Siamo sicuri che questo elemento contiene una serie di valori interi e vogliamo moltiplicarli per tre salvando tutto in un nuovo array.
Come per l’esempio precedente, questo sarà l’array che avremo come riferimento:
var nums = [ 1, 3, 6, 9, 12 ];
Sono sicuro che sai che con il classico JavaScript possiamo scrivere qualcosa del genere:
for( var i = 0; i < nums.length; i++ ){ nums[i] = nums[i] * 3; } console.log( nums );
Con il codice precedente ho fatto il piccolo errore di non creare il nuovo array ma in fin dei conti poco importa perché anche in questo caso Underscore.js ci mostra la sua utilità permettendoci di svolgere questa operazione con una singola riga di codice:
var triple = _.map( nums, function( num ){ return num * 3; }); console.log( triple );
Array
Abbiamo finito di elencare alcune delle funzioni più interessanti per quanto riguarda la categoria Collection e adesso è giunto il momento di andare a fondo (o fare un deep dive come direbbero in inglese) per quanto riguarda le funzioni che sono specifiche per gli array.
Ti ricordo che consultando direttamente la documentazione sul sito http://underscorejs.org potrai avere le descrizioni delle varie funzioni, ma non voglio perdere l’occasione di elencarti le mie preferite.
Zip
Al contrario di quello che potrebbe farci pensare il nome, la funzione zip()
non serve a far comprimere un array all’interno dell’omonimo archivio; come farebbe in fin dei conti.
Invece la sua utilità è quella che ci permette di raggruppare diversi valori contenuti in un array rispettando le loro chiavi. Questa funzionalità è molto utile quando abbiamo una serie di valori che dobbiamo collezionare e organizzare all’interno di una pagina web.
Vediamo subito quali sono gli array di partenza:
var nomi = [ "Andrea", "Eugenio", "Daniele" ], cognomi = [ "Barghigiani", "Petullà", "Scasciafratte" ], eta = [ 32, 29, 26 ];
Vediamo un po’ come sia possibile raggiungere una funzionalità simile a quella espressa nella descrizione precedente con un classico codice JavaScript:
var aggregati = []; for( var i = 0; i < nomi.length; i++ ){ aggregati.push( [nomi[i], cognomi[i], eta[i]] ); } console.log( aggregati );
Ormai dovresti immaginare quello che sto per dire, è da tutto l’articolo che ripeto la stessa frase. Underscore.js ci offre una sintassi più asciutta e comprensibile 🙂
var aggregati = _.zip( nomi, cognomi, eta ); console.log( aggregati );
Vorrei soltanto farti notare che con console.log() in questo caso non farai altro che ottenere un risultato del genere: Array [ Array[3], Array[3], Array[3] ]. Non ti spaventare, se utilizzi gli strumenti per lo sviluppatore potrai cliccare su ogni singola voce e scoprire i nuovi valori che sono stati aggregati.
Intersection
Questa è molto semplice da comprendere, tutto quello che bisogna fare è un piccolo esercizio di immaginazione e pensare a un array come se fosse un insieme.
Ricordi quando eravamo piccoli e sui banchi delle elementari le maestre ci hanno insegnato concetti come gli insiemi e le operazioni unione, differenza e intersezione? Ebbene la funzione intersection()
ci permette proprio di prendere una serie di array e ottenere come risultato la loro intersezione.
Da qui in avanti pubblicherò soltanto le soluzioni scritte sfruttando la libreria Underscore.js perché altrimenti rischiamo di far diventare questo articolo fin troppo lungo. Se la cosa ti disturba e ti interessa vedere come sia possibile raggiungere lo stesso risultato con JavaScript vanilla, fammelo sapere all’interno dei commenti oppure proponi direttamente la tua soluzione creando una pull request del repository GitHub 😉
var ins1 = [ 1, 2, 3, 4, 5, 6], ins2 = [ 2, 4, 6, 8 ], ins3 = [ 1, 4, 5, 9, 12, 15]; var int = _.intersection( ins1, ins2, ins3 ); console.log( int );
Controllando la console noterai che l’unico valore che contiene l’array int
è soltanto il numero 4. Fai pure i tuoi calcoli, ma questo è l’unico valore che viene condiviso da tutti e tre gli array.
indexOf
Hai mai avuto la necessità di conoscere l’indice di un valore contenuto in un array? So che può essere un caso molto raro, ma quando ci viene richiesto di trovare l’indice di un determinato valore spesso dobbiamo fermare quello che stiamo facendo e scrivere da soli una funzione che chieda quale sia il valore da cercare e restituirne l’indice.
Sicuramente non è niente di complicato, ma grazie a Underscore.js abbiamo una funzione dedicata che ci permetterà di risparmiare qualche minuto prezioso.
var arr = [ 23, "ciao", 42, "mondo" ]; var index = _.indexOf( arr, 42 ); console.log( index );
Objects
Arriviamo quindi alla categoria che ci offre delle facili soluzioni per lavorare con gli oggetti; non perdiamo tempo e andiamo subito a scoprire la prima funzione che ti ho messo da parte.
Pairs
Sappiamo tutti che un oggetto in JavaScript è una raccolta di chiave – valore. In alcuni casi torna comodo poter raggruppare in diversi array queste coppie per poterci lavorare sopra, un po’ come segue:
var obj = { nome: "Andrea", cognome: "Barghigiani", eta: 32 } var accoppiato = _.pairs( obj ); console.log( accoppiato );
Come già successo in precedenza la funzione pairs()
creerà un array multidimensionale, ovvero un array all’interno del quale gli indici sono popolati dal nome della proprietà. Talvolta ci riferiamo a questi con termini più matematici identificandoli come matrice.
Adesso che abbiamo raggiunto questo risultato e trasformato un oggetto in un array, potremmo anche utilizzare le funzioni dedicate a questi elementi che Underscore.js stesso ci mette a disposizione. Questo però è un argomento che vorrei trattare al termine di questo articolo, che ne dici se continuiamo a studiare qualche funzione dedicata agli oggetti?
Extend
Talvolta capita che all’interno del nostro codice abbiamo il bisogno di dover estendere un oggetto che stiamo utilizzando, peccato che con JavaScript vanilla avremmo il bisogno di dover utilizzare Object.prototype
e altre complesse strutture. Per fortuna oggi possiamo usare una sintassi molto più semplice.
var obj = { nome: "Andrea", cognome: "Parghigiani" } var obj = _.extend( obj, { cognome: "Barghigiani", eta: 32 }); console.log( obj);
Adesso, se andiamo ad aprire la console possiamo notare che l’oggetto obj
non è soltanto stato esteso ma che anche la proprietà cognome
è stata sostituita con il valore corretto.
Questo significa che la funzione extend()
non aggiunge soltanto proprietà e metodi a un oggetto esistente, ma se trova delle chiavi esistenti sostituisce il valore in esse contenuti supponendo che quello passato dall’oggetto dichiarato come secondo parametro sia più aggiornato e corretto rispetto al primo.
isEqual
Come ti dico fin dall’inizio di questo articolo, la libreria Underscore.js nasce per fornire delle soluzioni pratiche allo sviluppatore JavaScript. Proprio come jQuery offre le sue funzioni per semplificare il nostro lavoro. Quella che ti sto per presentare ci aiuta in un altro caso specifico.
Ti è mai capitato di dover confrontare due oggetti per scoprire se sono uguali o meno?
Probabilmente hai provato a fare una cosa del genere:
var obj1 = { nome: "Andrea", cognome: "Barghigiani", eta: 32 }; var obj2 = { nome: "Andrea", cognome: "Barghigiani", eta: 32 } var confronto = obj1 == obj2; console.log( confronto );
Se hai consultato la console ti sarai accorto che confronto
restituisce false
, in fin dei conti questo ragionamento non fa una piega.
Confrontando gli oggetti in questo modo stiamo chiedendo a JavaScript se i due oggetti appartengono alla stessa istanza ed è ovvio che questo risponda in modo negativo. Gli oggetti hanno le stesse proprietà e valori, ma appartengono a due istanze diverse.
Però queste piccole sviste possono anche capitare mentre si programma e bisogna ammettere che non sempre siamo in grado di ricordarci come sia possibile confrontare gli oggetti dato che la sintassi di questa operazione è abbastanza complicata.
Ecco allora che una funzione come isEqual()
è più che benvenuta all’interno dei set di strumenti di uno sviluppatore. Utilizzando gli stessi oggetti già dichiarati possiamo scrivere quanto segue:
var confronto = _.isEqual( obj1, obj2 ); console.log( confronto );
Ed ecco che adesso all’interno della nostra console è apparso true
che ci svela che, per i nostri interessi, i due oggetti sono uguali.
La cosa bella è che all’interno di questa categoria esistono moltissime altre funzioni isX()
dove potrai sostituire la X con termini come Empty, Function, Date, RegExp e moltissimi altri. Come successo per isEqual()
ciascuna ci restituisce il valore booleano per capire se l’oggetto passato risponde alle nostre richieste.
Functions
Siamo quasi alla fine di questo articolo, ma non farei bene il mio lavoro se non ti presentassi anche le funzioni che permettono di lavorare con… funzioni. Precedentemente quando ti ho presentato le diverse categorie di funzioni in Underscore.js ho scherzato un po’ sulla loro utilità, ma adesso sono estremamente serio perché quello che troveremo al suo interno è veramente interessante.
bind
Se hai già lavorato con jQuery sono sicuro che conosci bene questa funzione, praticamente ci permette di fissare una funzione a un oggetto. Ovvero ogni volta che viene chiamata la funzione fissata, il valore di this
verrà preso dall’oggetto collegato, indipendentemente da quello che viene passato come parametro.
var fun = function(saluto){ return saluto + ', ' + this.nome }; fun = _.bind(fun, {nome: "Andrea"}, 'Ciao'); console.log( fun("Salve") );
Come puoi notare da questo esempio, nelle prime righe di questo blocco di codice noi andiamo a creare la funzione fun()
che richiede come parametro una stringa, ma anche se questa viene indicata quando andiamo a utilizzare la funzione all’ultimo rigo il suo valore resta comunque Ciao.
E tutto questo senza neanche notare il fatto che il valore di this.nome
non è stato neanche passato 🙂
partial
All’interno delle nostre attività di programmazione capita molto spesso di avere una funzione che chiamiamo più e più volte indicando lo stesso parametro. Sarebbe carino che, al posto di riscrivere una funzione da capo, avere la possibilità di sfruttare la logica generale della funzione ma evitare di richiedere un parametro aggiuntivo.
Facciamo un esempio pratico, abbiamo creato la classica funzione sottrazione()
che accetta due parametri; il primo indica il numero completo mentre con il secondo possiamo indicare quanto vogliamo sottrarre.
Ma se per qualche motivo mi trovo a dover sottrarre 5 da una serie di valori? Sono obbligato a specificare tutte le volte il secondo parametro?
Grazie a Underscore.js non più:
var sottrazione = function(a, b) { return b - a; }; var sott5 = _.partial( sottrazione, 5 ); console.log( sott5( 45 ) );
Grazie a partial()
abbiamo creato la nuova funzione sott5()
che permette di fare proprio questo, sottrarre 5 ogni volta che viene chiamata.
after
Ti è mai capitato di dover richiamare una funzione soltanto dopo che la principale è stata eseguita un determinato numero di volte?
Se ti è capitato di scrivere codice jQuery, molte sue funzioni hanno la possibilità di inserire altre funzioni come callback che vengono chiamate in automatico al completamento della prima; personalmente però non ho trovato un modo semplice di richiamarla soltanto dopo che la prima è stata lanciata X volte.
Anche in JavaScript si sta muovendo qualcosa grazie alla nuova sintassi ECMAScript 6 e alle sue Promises, ma questo è un argomento che approfondiremo in un altro articolo.
Oggi voglio mostrarti come sia possibile fare questa cosa sfruttando una funzione che viene messa a disposizione da Underscore.js e che con molta fantasia si chiama after()
. L’esempio che ti riporto qua sotto è il primo che farà uso della pagina HTML collegata, vediamo un po’ che cosa ho preparato.
var btn = document.querySelector('button'), cb; cb = _.after(4, function() { alert(':)'); }); btn.onclick = function fun(){ cb(); }
Il codice che vedi qua sopra resta in ascolto dell’evento onclick sul nostro bottone e grazie ad after()
dalla quarta pressione farà apparire un alert che in questo caso contiene una emoticon, ma come puoi immaginare potrebbe contenere qualsiasi stringa.
Utility
Eccoci giunti alla categoria conclusiva delle funzioni che ci mette a disposizione questa interessante libreria. La selezione personale che troverai qua sotto ti permetterà di interagire ancora meglio con lo stesso Underscore.js e con il tuo codice in generale.
times
La prima funzione che voglio affrontare con te è quella che ci permetterà di ripetere un numero determinato di volte una funzione appartenente al nostro codice. L’esempio che trovi qua sotto è molto stupido ma ti permetterà di capire sicuramente il funzionamento e la sintassi di questa funzione.
_.times( 3, function fun(){ alert( "Ciao Andrea!" )} );
La funzione time()
accetta due parametri come si può vedere. Il primo è il numero di ripetizioni mentre il secondo è la funzione che deve essere ripetuta.
mixin
Se con questo nome ti suona qualche campanello significa che molto probabilmente hai già avuto a che fare con Sass e la cosa mi fa un’incredibile piacere. Se così non fosse ti ricordo che abbiamo pubblicato un corso specifico su questo precompilatore, ma oggi il nostro interesse è rivolto verso un altro linguaggio.
Allo stesso modo però anche Underscore.js mette a disposizione questo interessante strumento che ci permette di estendere questa stessa libreria con le nostre funzioni. Qua sotto ti mostro come potrai creare la tua funzione interna per aggiungere la maiuscola alla prima parola di una frase:
_.mixin({ capitalize: function(string) { return string.charAt(0).toUpperCase() + string.substring(1).toLowerCase(); } }); var test = _.capitalize( "cIAo SoNO iO" ); console.log(test);
Insomma Underscore.js non smette mai di stupirci, nel caso in cui possa mancare qualcosa possiamo sempre crearci lenostre funzioni 🙂
template
Diciamo che mi sono salvato questa funzione per ultima, ma è anche una delle più famose che ci permettono di utilizzare questa libreria come un vero e proprio template engine!
Sempre più spesso capita che per le nostre Single Page Application (SPA), JavaScript è il linguaggio di base che ci aiuta a popolare il nostro codice HTML con le informazioni che possiamo ottenere dal database e dalle operazioni Ajax che vengono svolte.
Grazie a template()
possiamo creare proprio questa funzionalità che ci aiuterà a creare le viste delle nostre applicazioni senza dover dipendere da altre librerie che potrebbero appesantire il nostro codice.
var linguaggi = [ 'PHP', 'JavaScript', 'CSS', 'HTML', 'Ruby', 'Go' ], linguaggiTemplate = _.template('<li><%= linguaggio %></li>'), content = ''; _.each(linguaggi, function(linguaggio, index, linguaggi) { content += linguaggiTemplate({ linguaggio: linguaggio }); }); var container = document.createElement('ol'); container.innerHTML = content; document.body.appendChild(container);
Ed ecco fatto, risponverando un po’ anche i concetti di each()
che abbiamo conosciuto precedentemente, siamo stati in grado di sfruttare JavaScript per creare una lista ordinata che potrà essere successivamente modificata attraverso le operazioni Ajax.
Questa funzione diventa incredibilmente utile man mano che scriviamo le nostre viste e arricchiamo la nostra applicazione. Riconosco che l’esempio può sembrare fin troppo semplice, ma vista la lunghezza di questo articolo non potevo fare diversamente.
Sei interessato a conoscere altri usi della funzione _.template() o vuoi approfondire altri aspetti che ti ho presentato? Usa pure i commenti che trovi qua sotto e fammi sapere che cosa desideri conoscere, sono sempre disponibile a darti una mano per migliorare la tua carriera e le tue conoscenze!
Ma insomma, vale la pena usare Underscore.js
Rispondo subito dicendo che dipende…
Personalmente ho scritto questo articolo per diversi motivi, primo fra tutti il fatto che questa libreria è presente all’interno del mio CMS preferito, è veramente semplice da richiamare al suo interno e da utilizzare.
Tra gli altri motivi che mi hanno spinto a scrivere questo articolo c’è anche il fatto che avevo bisogno di creare un punto di partenza per scrivere ulteriori articoli dove affronteremo le novità che sono state introdotte nelle ultime sintassi di JavaScript; molte delle quali rispecchiano alcune delle funzioni che abbiamo già visto.
Non ti posso nascondere che se sei interessato a una libreria leggera che permette di avere un numero maggiore di funzioni utili nello sviluppo JavaScript esiste anche un’altra soluzione che al momento è molto più aggiornata e mantenuta rispetto a Underscore.js e prende il nome di lodash.
Non ho preferenze di una sull’altra perché non passando le giornate a scrivere JavaScript probabilmente non sono in grado di apprezzarne le differenze, ma ti anticipo che esistono interessanti discussioni online che non mancherò di riportarti anche all’interno delle nostre newsletter.
Spero che questo articolo sia stato tanto utile per te quanto lo è stato per me scriverlo e ricorda una cosa, non dimenticarti di condividerlo con i tuoi colleghi e amici. Farai un favore sia a me che a loro 😉
Lascia un commento