Esistono tutta una serie di funzionalità Javascript che possono essere un'opportunità per velocizzare la stesura del proprio codice ma che spesso si trasformano in errori o comportamenti imprevisti non sempre semplici da identificare.
In un mio precedente articolo ho dato 10 SUGGERIMENTI, TRUCCHI E BEST PRACTICE IN JAVASCRIPT PER OTTIMIZZARE LE TUE APP, stavolta invece descriverò 3 altrettanti trucchi da evitare di utilizzare come best practice o eventualmente usare con cautela.
Utilizzo di una funzione prima di dichiararla
Nonostante Javascript sia definito come un linguaggio interpretato, ovvero che le sue operazioni vengono eseguite in modo sequenziale, la sua esecuzione da parte dell'interprete (il browser) permette l'utilizzo di funzioni all'interno del codice che non sono state ancora (sequenzialmente) dichiarate, in inglese tale situazione prende il nome di hoisted function (funzione sollevata).
L'esempio seguente è autoesplicativo:
// Chiamata alla funzione sollevata (hoisted)
eseguiSomma(7, 4);
// Dichiarazione della funzione
function eseguiSomma(num1, num2) {
console.log(num1 + num2);
}
Il risultato stampato in console, eseguendo il codice di cui sopra, sarà 11 (nonostante la funzione sia stata utilizzata prima della sua dichiarazione).
Personalmente preferisco dichiarare tutte le funzioni prima di qualsiasi tipo di codice operativo, sia per evitare di incappare in errori che per facilità di lettura del codice stesso in fase di modifica o di debug, tuttavia potrebbero esserci situazioni dove l'utilizzo appena proprosto può rivelarsi utile. In tutti i casi è necessario porre attenzione a come la funzione viene successivamente dichiarata perchè il risultato potrebbe non essere quello sperato, come nell'esempio seguente:
eseguiSomma(7, 4); // 11
eseguiSottrazione(7, 4); // TypeError: eseguiSottrazione is not a function
// Dichiarazione delle funzioni
function eseguiSomma(num1, num2) {
console.log(num1 + num2);
}
var eseguiSottrazione = function(num1, num2) {
console.log(num1 - num2);
};
Ci si aspetterebbe, che il risultato della seconda chiamata alla funzione sia 7 - 4 = 3, in realtà proprio per il modo in cui la funzione è stata successivamente dichiarata viene generato un errore perchè non viene riconosciuta appunto una chiamata ad una funzione: "Uncaught TypeError: eseguiSottrazione is not a function". Questo succede perchè le funzioni dichiarate con var, nonostante anch'esse vengano "sollevate" (hoisted), restituiscono come valore undefined nel caso vengano utilizzate prima della loro dichiarazione.
Omissione della parola chiave var
La dichiarazione di variabili, come indicato anche nel link dei suggerimenti inserito ad inizio articolo, può avvenire con o senza utilizzo del termine var anteposto alla dichiarazione stessa e senza che venga generato alcun errore. Questo succede perchè la rispettiva variabile verrà ugualmente creata ma il suo ambito sarà globale. Questo tipo di comportamento, nonostante a volte sia necessario avvalersene, può portare alla generazione di risultati inaspettati.
Un esempio spiega meglio la differenza tra utilizzare e non utilizzare il termine var per dichiarare una variabile:
miaPrimaVariabile = 'Ciao';
miaSecondaVariabile = 'Mondo';
var miaFunzione = function() {
var miaPrimaVariabile = 'Hello';
miaSecondaVariabile = 'World!';
};
miaFunzione();
console.log(miaPrimaVariabile);
console.log(miaSecondaVariabile);
Nel caso specifico, guardando all'interno della funzione, la prima variabile è stata dichiarata con var e quindi funziona a livello locale, la seconda senza var e quindi vale a livello globale. Eseguendo il codice di cui sopra, nonostante le due variabili contengano rispettivamente la parola "Ciao" e "Mondo", in console verrà stampato "Ciao" e "World!" in virtù del fatto che la seconda variabile, essendo il suo ambito globale, viene sovrascritta mentre la prima, nonostante il nome sia lo stesso di quella dichiarata fuori dalla funzione, funziona solo localmente all'interno di miaFunzione().
Da qui è importante fare attenzione oltre ad utilizzare in modo corretto la parola chiave var, anche al nome delle variabili in quanto utilizzando un nome identico tra variabile dentro e fuori le funzioni, a lunga andare, si rischia di rende meno leggibile e comprensibile il codice in fase di debug e di generare incongruenze in termini di aspettativa dei risultati.
Omissione del punto e virgola
A differenza di alcuni altri linguaggi, quali ad esempio il PHP, l'utilizzo del punto e virgola alla fine di una riga di codice in Javascript è opzionale in quanto esso viene inserito automaticamente, qualora non presente, in fase di esecuzione. Questo è un vantaggio in quanto agevola la scrittura di codice e non viene generato errore per eventuali dimenticanze tuttavia è anche un'arma a doppio taglio. Un esempio si ha nel caso in cui siamo abituati a scrivere codice indentando le aperture e chiusure delle parentesi a capo, pertanto una situazione come la seguente (secondo esempio nel codice sotto) genererebbe un errore di sintassi bloccante per l'esecuzione di tutto il resto del codice:
// Corretto
return {
'ok': false
};
// Genera errore
return
{
'ok': false
};
Il problema della generazione dell'errore è spiegato proprio dal fatto che Javascript inserisce automaticamente i punti e virgola in fondo alle righe di codice pertanto la situazione di cui sopra, nel caso del secondo esempio, viene interpretata come di seguito:
return; // il suo valore è undefined
// codice che genera errore in quanto e parentesi sono aperte senza riferire a niente
{
'ok': false
}
Onde evitare spiacevoli inconvenienti come quello appena esposto consiglio di inserire sempre il punto e virgola alla fine di ciascuna riga di codice in modo da avere maggior controllo sul flusso e, quantomeno secondo le mie preferenze, di aprire le parentesi di funzioni o quant'altro sulla stessa riga del comando a cui sono riferite.
Sicuramente con questi accorgimenti risparmierete tempo spesso perso in debug alla ricerca di errori che in realtà errori veri e propri non sono.
Complimenti
Grazie del feedback Eduardo!