Uno degli elementi chiave di un programma, in questo caso di Javascript, sono le funzioni. Una funzione raccoglie in sé tutte le istruzioni per assolvere ad un determinato compito all'interno di un programma.
Una funzione, quindi, è una parte (relativamente) autonoma di un programma in quanto assolve ad un compito specifico che può essere ripetuto più volte in diversi punti del programma stesso.
Organizzare un programma in funzioni consente una maggiore pulizia del codice sorgente e, soprattutto, facilita il riutilizzo del codice e, di conseguenza, consente di creare programmi più snelli e semplici da mantenere ed aggiornare.
-
1. Le funzioni in JavaScript
Screenshot Fastweb Plus
Una funzione è un insieme di istruzioni racchiuse in un blocco di codice, che può essere contraddistinto da un nome, può accettare argomenti o parametri di ingresso e restituire valori.
Lo schema sintattico per la definizione di una funzione è:
function nome(argomenti) {
// istruzioni
}
Una volta dichiarata, la funzione non viene eseguita subito, diciamo solo all'engine JavaScript che al blocco di codice indicato viene assegnato un nome. L'esecuzione vera e propria avviene con l'invocazione o chiamata:
nome(valori);
I valori inseriti nella chiamata di una funzione vengono passati, cioè assegnati, ai corrispondenti argomenti della definizione della funzione. In questo esempio:
function somma() {
var z = 11 + 5;
return z;
}
var risultato = somma();
Abbiamo definito una funzione senza argomenti che somma due interi e restituisce il risultato. L'invocazione della funzione fa sì che venga eseguita la somma ed il risultato venga assegnato alla variabile risultato.
Così però la funzione somma() è in grado di sommare soltanto i due numeri nel blocco di istruzioni. Per renderla più generale è opportuno introdurre due argomenti che rappresenteranno i numeri da sommare:
function somma(x, y) {
var z = x + y;
return z;
}
In questo caso i valori da sommare verranno passati alla funzione somma() al momento dell'invocazione:
var risultato = somma(11, 5);
-
2. L'array arguments
Screenshot Fastweb Plus
Possiamo non definire alcun argomento nella definizione di somma() ed accedere ai valori passati in fase di chiamata tramite un array speciale predefinito: arguments.
La funzione si presenterebbe così:
function somma() {
var z = arguments[0] + arguments[1];
return z;
}
In questo caso non specifichiamo gli argomenti a fianco al nome della funzione, ma accediamo ad essi sfruttando l’array predefinito.
La disponibilità di arguments consente di creare funzioni con un numero di parametri non definito. Ad esempio, possiamo sommare un numero indefinito di valori:
function somma() {
var z = 0;
var i;
for (i in arguments) {
z = z + arguments[i];
}
return z;
}
E potremmo chiamare la funzione per sommare un qualsiasi numero di valori:
somma(2, 78);
somma(17, 32, 4, 19, 52);
Con l'avvento di ECMAScript 6, altri elementi arricchiscono la flessibilità della gestione degli argomenti come la possibilità di specificare dei valori di default:
function somma(x = 0, y = 0) {
var z = x + y;
return z;
}
Così se al momento della chiamata non viene passato un argomento, ad esso viene assegnato il valore di default specificato, invece del valore undefined. Quindi, ad esempio, la chiamata somma() senza argomenti restituirà il valore 0 anziché NaN.
-
3. Specificare il rest parameter
Screenshot Fastweb Plus
Altra novità introdotta con la nuova versione dello standard è la possibilità di specificare il rest parameter: una notazione speciale per indicare un elenco indefinito di argomenti aggiuntivi. Supponiamo di voler definire una funzione che implementa diverse operazioni aritmetiche e prende come primo argomento il nome dell'operazione da eseguire ed a seguire un numero variabile di valori su cui effettuare l'operazione.
function eseguiOperazione(x, ...y) {
var z = 0;
switch (x) {
case "somma":
for (i in y) {
z = z + y[i];
}
break;
case "moltiplica":
for (i in y) {
z = z * y[i];
}
break;
case "dividi":
z = y[0]/y[1];
break;
default:
z = NaN;
break;
}
return z;
}
L’argomento x rappresenta il nome dell'operazione da eseguire e l’argomento y il resto dei valori da passare alla funzione. La notazione dell'argomento preceduto dai puntini cattura l'elenco degli argomenti successivi al primo e lo rende disponibile all'interno della funzione sotto forma di array.
L'approccio è simile all'array predefinito arguments, ma mentre questo cattura tutti gli argomenti della funzione, il rest parameter cattura soltanto gli argomenti in più rispetto a quelli specificati singolarmente.
Possiamo invocare la funzione in uno dei seguenti modi:
eseguiOperazione("somma", 12, 54, 2, 7, 12);
eseguiOperazione("moltiplica", 4, 11, 32);
eseguiOperazione("dividi", 45, 9, 6, 17);
La stessa notazione del rest parameter può essere utilizzata nelle chiamate a funzioni che prevedono diversi argomenti. In questo caso, si parla di spread operator, cioè di un operatore che sparge i valori contenuti in un array sugli argomenti di una funzione, come nel seguente esempio:
var addendi = [8, 23, 19, 72, 3, 39];
somma(...addendi);
La chiamata con lo spread operator è equivalente alla seguente chiamata:
somma(8, 23, 19, 72, 3, 39);
-
4. L’istruzione return
Screenshot Fastweb Plus
Nel corpo della funzione può essere presente zero o più volte l'istruzione return che consente di terminare e restituire un valore al codice che l'ha chiamata. Questo consente di assegnare ad una variabile il valore restituito da una funzione o utilizzare una funzione all'interno di una espressione.
In questo esempio:
function decodifica(numero) {
switch(numero) {
case "uno":
return 1;
break;
case "due":
return 2;
break;
case "tre":
return 3;
break;
default:
return NaN;
break;
}
}
La funzione termina e restituisce un valore non appena individua una corrispondenza con l'argomento. Tuttavia, è buona norma limitare il numero di return presenti in una funzione, riducendoli a uno soltanto. Questo rende il codice più leggibile e manutenibile.
-
5. Variabili globali e locali: lo scope
Screenshot Fastweb Plus
Lo scope o ambito di visibilità di una variabile è la parte di uno script all'interno del quale si può fare riferimento ad essa. Le variabili dichiarate all'interno di una funzione sono dette locali alla funzione dal momento che sono accessibili soltanto all'interno del suo corpo. Le variabili dichiarate fuori da qualsiasi funzione sono dette globali e sono accessibili da qualsiasi punto dello script, anche all'interno di funzioni.
Qui:
var x = 10;
var y;
function incrementa(){
var z = 5;
x = x + z;
}
incrementa();
y = x + 1;
Dichiariamo due variabili globali x e y accessibili anche all'interno della funzione incrementa() e la funzione accede a x per incrementarla del valore della variabile locale z. Il valore della variabile x dopo l'invocazione della funzione incrementa() sarà 15 ed il valore finale assegnato a y sarà 16.
Variabili locali e globali possono avere lo stesso nome, ma si vengono a creare delle ambiguità la cui risoluzione dipende dalla regola secondo cui si fa riferimento all'ambito di visibilità più vicino all'utilizzo della variabile. Dunque, è opportuno dichiarare le variabili all'inizio dello scope, ad esempio all'inizio del corpo di una funzione.
-
6. L’istruzione let
Screenshot Fastweb Plus
Per creare uno scope specifico per una o più variabili possiamo ricorrere all'istruzione let che, definita dalle specifiche di ECMAScript 6, consente di dichiarare una o più variabili in modo analogo a var, ma a differenza di quest'ultima limita lo scope della variabile al blocco di codice, all'istruzione o all'espressione in cui viene utilizzata. Nel seguente codice:
var x = 10;
var y;
{
let x = 20;
y = x + 1;
}
y = x + y;
avremo uno scope a livello di blocco di codice in cui la variabile x dichiarata tramite let nasconde quella esterna dichiarata con var. Il risultato finale combina i valori delle due variabili omonime.
Utilizzare l'istruzione let è utile nelle iterazioni, come ad esempio nel for in cui dichiariamo ed utilizziamo la variabile “i” soltanto all'interno del ciclo, evitando eventuali collisioni con altre variabili omonime definite in scope più esterni:
var x = 0;
for (let i = 0; i < 10; i++) {
x = x + 1;
}
-
7. Funzioni predefinite
Screenshot Fastweb Plus
JavaScript dispone di alcune funzioni predefinite utili in alcune attività e invocabili in qualsiasi punto dello script.
Le funzioni parseInt() e parseFloat() consentono di convertire una stringa rispettivamente in un valore numerico intero e decimale. La prima prevede due parametri: la stringa da convertire e uno opzionale che indica la base del sistema di rappresentazione numerica utilizzato. La seconda prevede un solo argomento e restituisce un valore numerico intero o decimale in base alla presenza del separatore decimale.
La funzione isNaN() prende un argomento e restituisce true se il suo valore è NaN, cioè non è un valore numerico valido, false altrimenti; isFinite() restituisce true se il valore del suo argomento è diverso da Infinity e da NaN.
Quando una stringa rappresenta un URI è opportuno utilizzare la funzione encodeURI() che esclude dalla codifica i caratteri , /?:@&=+$#.La controparte è la funzione decodeURI() che restituisce la stringa decodificata.
La funzione encodeURIComponent() codifica anche i caratteri speciali esclusi dalla encodeURI(): è pensata per codificare i valori di eventuali parametri passati in un URI. La corrispondente funzione per la decodifica è decodeURIComponent().
Per saperne di più:A cosa serve Javascript e come imparare a programmarlo