Articolo originale: https://www.freecodecamp.org/news/var-let-and-const-whats-the-difference/

Molte nuove funzionalità uscirono con ES2015 (ES6). E ora, visto che è il 2020, è dato per scontato che molti programmatori JavaScript hanno familiarizzato con e hanno iniziato a usare queste funzionalità.

Anche se questa assunzione può essere parzialmente corretta, è sempre possibile che alcune di queste funzionalità rimangano un mistero per alcuni programmatori.

Una delle funzionalità che è stata introdotta da ES6, è l'aggiunta di let e const, che possono essere usati per la dichiarazione delle variabili. La domanda è, cosa li rende diversi dal buon vecchio var che abbiamo sempre usato? Se hai ancora dubbi su questa cosa, questo è l'articolo che fa per te.

In questo articolo, discuteremo var, let e const e le differenze del loro ambito, uso e issamento. Mentre leggi, nota le differenze che evidenzierò.

var

Prima dell'arrivo di ES6, le dichiarazioni con var facevano da padrone. Ma ci sono problemi associati alla dichiarazione delle variabili con var. Per questo era necessario avere nuovi modi per dichiarare le variabili. Prima di arrivare a questi problemi vediamo di capire meglio var.

Ambito di var

Ambito (scope in inglese) significa dove queste variabili sono disponibili per essere usate. Le dichiarazioni con var hanno ambito globale, o della funzione/locale.

L'ambito è globale quando una variabile è dichiarata con var al di fuori di una funzione. Questo significa che qualsiasi variabile dichiarata con var al di fuori del blocco di una funzione è disponibile per essere usata nell'intera finestra.

var ha l'ambito della funzione quando è dichiarato dentro una funzione. Questo significa che è disponibile e può essere usato solo dentro la funzione.

Per capire meglio, guarda al seguente esempio.

    var greeter = "hey hi";
    
    function newFunction() {
        var hello = "hello";
    }

Qui, greeter ha ambito globale perché esiste al di fuori di una funzione mentre hello ha ambito della funzione. Qundi non possiamo avere accesso alla variabile hello dal di fuori della funzione. Quindi se facciamo così:

    var tester = "hey hi";
    
    function newFunction() {
        var hello = "hello";
    }
    console.log(hello); // error: hello is not defined

Otterremo un errore ("error: hello is not defined" che significa "errore: hello non è definito") come risultato del fatto che hello non è disponibile al do fuori della funzione.

Le variabili var possono essere ri-dichiarate e aggiornate

Questo significa che possiamo fare questo nello stesso ambito e non riceveremo un errore.

    var greeter = "hey hi";
    var greeter = "say Hello instead";

e anche questo

    var greeter = "hey hi";
    greeter = "say Hello instead";

Hoisting di var

L'hoisting è un meccanismo di JavaScript dove la dichiarazione di variabili e funzioni è spostato all'inizio del loro ambito prima dell'esecizione del codice. Questo significa che se facciamo:

    console.log (greeter);
    var greeter = "say hello"

è interpretato come

    var greeter;
    console.log(greeter); // greeter is undefined
    greeter = "say hello"

Quindi variabili var sono issate all'inizio del loro ambito e inizializzate con un valore di undefined.

Problema con var

C'è una debolezza che viene con var. Userò l'esempio seguente per spiegare:

    var greeter = "hey hi";
    var times = 4;

    if (times > 3) {
        var greeter = "say Hello instead"; 
    }
    
    console.log(greeter) // "say Hello instead"

Qui, visto che times > 3 restituisce true, greeter è ridefinito a "say Hello instead". Mentre questo non è un problema se vuoi consciamente che greeter sia ridefinito, diventa un problema quando non ti accorgi che una variabile greeter è già stata definita precedentemente.

Se hai usato greeter in altre parti del tuo codice, potresti avere una sorpresa sull'output che ottieni. Questo causerà probabilmente molti bug nel tuo codice ed è il motivo per cui let e const sono necessari.

let

let è ora preferito per la dichiarazione delle variabili. Non è una sorpresa perché è stato creato come miglioramento di var. Risolve anche il problema con var che abbiamo appena visto. Vediamo perché.

let ha ambito del blocco

Un blocco è un pezzo di codice delimitato da {}. Qualsiasi cosa dentro parentesi graffe è un blocco.

Quindi una variabile dichiarata dentro un blocco con let è solo disponibile per essere usata dentro quel blocco. Fammi spiegare con un esempio:

   let greeting = "say Hi";
   let times = 4;

   if (times > 3) {
        let hello = "say Hello instead";
        console.log(hello);// "say Hello instead"
    }
   console.log(hello) // hello is not defined

Vediamo che usare hello al di fuori del suo blocco (le parentesi graffe dentro cui è definita) restituisce un errore. Questo è perché le variabili let hanno ambito di blocco.

let può essere aggiornato ma non ridichiarato.

Esattamente come var,  una variabile dichiarata con let può essere aggiornata dentro l'ambito. Ma a differenza di var, una variabile let non può essere ridiachiarata nel suo ambito. Quindi mentre questo funzionerebbe:

    let greeting = "say Hi";
    greeting = "say Hello instead";

questo restituisce un errore:

    let greeting = "say Hi";
    let greeting = "say Hello instead"; // error: Identifier 'greeting' has already been declared

D'altro canto, se la stessa variabile è definita in ambiti diversi, non ci sarà un errore:

    let greeting = "say Hi";
    if (true) {
        let greeting = "say Hello instead";
        console.log(greeting); // "say Hello instead"
    }
    console.log(greeting); // "say Hi"

Perché non c'è un errore? Perché entrambe le istanze sono trattate come variabili differenti visto che hanno un ambito diverso.

Questo fatto rende let una scelta migliore di var. Quando usi let non devi preoccuparti se hai già usato un nome per una variabile, visto che una variabile esiste solo dentro il suo ambito.

Inoltre, visto che una variabile non può essere dichiarata più di una volta dentro un ambito, il problema discussio prima che accade con var non si presenta.

Hoisting di let

Proprio come  var, l'hoisting porta le dichiarazioni con let all'inizio dell'ambito. A differenza di var che è inizializzato come undefined, la parola chiave let non è inizializzata. Quindi se provi a usare una variabile let prima della sua dichiarazione, otterrai un errore Reference Error.

Const

Le variabili dichiarate con const mantengono valori costanti. Le dichiarazioni con const hanno delle similitudini con le dichiarazioni con let.

Le dichiarazioni const hanno ambito di blocco

Come le dichiarazioni let, le dichiarazioni const possono essere usate solo dentro il blocco dentro cui sono state dichiarate.

Le dichiarazioni const non possono essere aggiornate o ri-dichiarate

Questo significa che il valore di una variabile dichiarato con const rimane lo stesso all'interno dell'ambito. Non può essere aggiornato o ri-dichiarato. Quindi se dichiaramo una variabile con const, non possiamo fare questo:

    const greeting = "say Hi";
    greeting = "say Hello instead";// error: Assignment to constant variable. 

né questo:

    const greeting = "say Hi";
    const greeting = "say Hello instead";// error: Identifier 'greeting' has already been declared

Ogni dichiarazione const deve quindi essere inizializzata al momento della dichiarazione.

Questo comportamento è in un certo qual modo differente quando si considerano gli oggetti dichiarati con const. Mentre un oggetto dichiarato con const non può essere aggiornato, le sue proprietà possono essere cambiate. Quindi, se dichiaramo un oggetto con const in questo modo:

    const greeting = {
        message: "say Hi",
        times: 4
    }

anche se non possiamo fare questo:

    greeting = {
        words: "Hello",
        number: "five"
    } // error:  Assignment to constant variable.

possiamo fare questo:

    greeting.message = "say Hello instead";

Questo cambierà il valore di greeting.message senza restituire alcun errore.

Hoisting di const

Proprio come let, l'hoisting porta le dichiarazioni con const all'inizio dell'ambito ma non sono inizializzate.

Quindi in caso tu non abbia notato le differenze, eccole qui:

  • le dichiarazioni con var  hanno ambito globale o di funzione, mentre le dichiarazioni con let e const hanno ambito di blocco.
  • Le variabili var possono essere aggiornate o ri-dichiarate dentro il loro ambito; le variabili let possono essere aggiornate ma non re-dichiarate; le variabili const non possono essere né aggiornate né re-dichiarate.
  • L'hoisting porta tutte le dichiarazioni in cima al loro ambito. Ma mentre le varabili var sono inizializzate con undefined, le variabili let e const non sono inizializzate.
  • Mentre var e let possono essere dichiarate senza essere inizializzate, const deve essere inizializzato durante la dichiarazione.

Hai domande o aggiunte? Fammelo sapere!

Grazie per aver letto :)