Lezione 4 — Tipi di dato primitivi in JavaScript: Guida Completa

Scopri tutto sui tipi di dato primitivi in JavaScript: String, Number, Boolean, Null, Undefined, Symbol e BigInt. Impara a gestirli correttamente per evitare bug comuni.

Introduzione ai Tipi di Dato in JavaScript

Benvenuti alla quarta lezione del nostro corso "Impara JavaScript in 50 lezioni". In questa lezione ci immergeremo in uno dei concetti più fondamentali di qualsiasi linguaggio di programmazione: i tipi di dato.

JavaScript è un linguaggio a tipizzazione dinamica. Cosa significa questo in termini pratici? Significa che, a differenza di linguaggi come Java o C++, non è necessario dichiarare esplicitamente il tipo di una variabile al momento della sua creazione. Una variabile può contenere un numero e, nella riga successiva, può essere riassegnata a una stringa senza che il compilatore generi un errore.

Sebbene questa flessibilità sia un vantaggio in termini di velocità di sviluppo, può portare a errori sottili se non si comprende come JavaScript gestisce i dati "sotto il cofano". I tipi di dato si dividono principalmente in due grandi categorie: i Primitivi e gli Oggetti. In questa lezione ci concentreremo esclusivamente sui primi.

Cosa sono i Tipi Primitivi?

Un valore primitivo è un dato che non è un oggetto e non ha metodi o altre proprietà. In termini tecnici, i primitivi sono immutabili. Questo non significa che non puoi cambiare il valore di una variabile, ma che il valore stesso, una volta creato, non può essere modificato.

Per esempio, se hai la stringa "Ciao", non puoi cambiare la prima lettera in "G" modificando la stringa originale; devi invece creare una nuova stringa "Giao" e assegnarla alla variabile.

Vediamo nel dettaglio i 7 tipi primitivi di JavaScript.

1. Number e BigInt: Gestire i Numeri

Il tipo Number

In JavaScript, non esiste una distinzione tra numeri interi (integer) e numeri a virgola mobile (float). Tutti i numeri sono rappresentati come numeri a virgola mobile a 64 bit (standard IEEE 754).

// Esempi di tipo Number
let intero = 42;            // Numero intero
let decimale = 3.14159;     // Numero con virgola
let esponente = 2e5;        // Notazione scientifica (2 * 10^5 = 200000)
let infinito = Infinity;    // Valore speciale per divisioni per zero
let nonNumero = NaN;        // Notazione per "Not a Number"

console.log(typeof intero);    // "number"
console.log(typeof decimale);  // "number"

Attenzione al NaN: NaN (Not a Number) appare quando un'operazione matematica fallisce (ad esempio, provare a moltiplicare una stringa per un numero). È importante sapere che NaN è, paradossalmente, di tipo "number".

Il tipo BigInt

Il tipo Number ha un limite di precisione (il valore massimo sicuro è Number.MAX_SAFE_INTEGER, ovvero $2^{53}-1$). Per gestire numeri interi arbitrariamente grandi, JavaScript ha introdotto BigInt.

Si crea aggiungendo una n alla fine del numero:

const numeroEnorme = 9007199254740991n;
const ancoraPiùGrande = BigInt("900719925474099254740992");

console.log(typeof numeroEnorme); // "bigint"

2. String: La manipolazione del testo

Le stringhe sono sequenze di caratteri utilizzate per rappresentare testo. In JavaScript possiamo definirle in tre modi:

  1. Apici singoli (' '): Standard.
  2. Apici doppi (" "): Standard.
  3. Backtick (``): Introdotti con ES6, permettono l'interpolazione e le stringhe multilinea.
const nome = "Mario";
const saluto = 'Ciao ' + nome; // Concatenazione classica

// Template Literals (i più potenti)
const messaggio = `Benvenuto ${nome}!\
Oggi è un bellissimo giorno per programmare.`;

console.log(messaggio);
/* 
Output:
Benvenuto Mario!
Oggi è un bellissimo giorno per programmare.
*/

Perché usare i Template Literals? Permettono di inserire espressioni JavaScript direttamente all'interno della stringa usando ${}, rendendo il codice molto più leggibile rispetto alla concatenazione con l'operatore +.

3. Boolean: La logica binaria

Il tipo Boolean rappresenta un valore logico e può avere solo due stati: true (vero) o false (falso).

I booleani sono il cuore delle strutture di controllo (come l'istruzione if).

let isOnline = true;
let hasPermission = false;

if (isOnline && !hasPermission) {
    console.log("L'utente è connesso ma non ha i permessi.");
}

Concetto di Truthy e Falsy

In JavaScript, ogni valore ha un valore booleano intrinseco quando viene valutato in un contesto logico.

  • Valori Falsy: false, 0, "" (stringa vuota), null, undefined, NaN.
  • Valori Truthy: Tutto il resto (incluse stringhe non vuote, numeri diversi da zero, array e oggetti).

4. Undefined e Null: L'assenza di valore

Questi due tipi spesso confondono i principianti perché entrambi rappresentano "vuoto", ma hanno significati semantici diversi.

Undefined

undefined significa che una variabile è stata dichiarata, ma non le è stato ancora assegnato alcun valore.

let x;
console.log(x); // undefined

Null

null è un valore che viene assegnato intenzionalmente dallo sviluppatore per indicare che una variabile è vuota o non ha un valore.

let utenteCorrente = null; // Dico esplicitamente: "al momento non c'è nessun utente"

Il bug storico: Se provi a fare typeof null, JavaScript restituirà "object". Questo è un errore di progettazione delle prime versioni del linguaggio che non è mai stato corretto per non rompere i siti web esistenti. Ricorda: null è un primitivo, non un oggetto!

5. Symbol: L'identità unica

Il tipo Symbol è stato introdotto in ES6. Un simbolo è un valore primitivo unico e immutabile. Anche se crei due simboli con la stessa descrizione, essi saranno diversi.

const sym1 = Symbol("id");
const sym2 = Symbol("id");

console.log(sym1 === sym2); // false

I simboli vengono utilizzati principalmente per creare chiavi di proprietà per gli oggetti che non devono collidere con altre chiavi, rendendole "nascoste" o private.

Esempi Pratici e Casi d'Uso

Immaginiamo di dover gestire i dati di un profilo utente in un'applicazione web. Vediamo come applichiamo i vari tipi di dato:

// Definizione di un profilo utente
const userProfile = {
    username: "DevMaster99",          // String: per il testo
    age: 28,                           // Number: per l'età
    isVerified: true,                  // Boolean: stato di verifica
    lastLogin: null,                   // Null: non ha mai effettuato l'accesso
    bio: undefined,                    // Undefined: l'utente non ha compilato la bio
    internalId: Symbol("userId"),    // Symbol: ID univoco non modificabile
    globalAccountBalance: 10000000000000000000n // BigInt: per saldi enormi
};

// Esempio di conversione (Type Casting)
let inputPrezzo = "19.99"; // Spesso i dati dagli input HTML sono stringhe
let prezzoNumerico = Number(inputPrezzo); // Convertiamo in Number per fare calcoli

console.log(prezzoNumerico + 1); // 20.99

Errori Comuni e FAQ

Perché "5" + 5 fa "55" e non 10?

Questo accade a causa della coercizione dei tipi. Quando usi l'operatore + tra una stringa e un numero, JavaScript converte automaticamente il numero in stringa e concatena i due valori. Per evitarlo, converti esplicitamente il valore: Number("5") + 5.

Qual è la differenza tra == e ===?

  • == (Uguaglianza astratta): Esegue la coercizione dei tipi. 5 == "5" è true.
  • === (Uguaglianza stretta): Controlla sia il valore che il tipo. 5 === "5" è false. Best Practice: Usa sempre === per evitare bug imprevisti.

Posso cambiare il tipo di una variabile?

Sì, perché JavaScript è a tipizzazione dinamica. Tuttavia, è sconsigliato farlo per chiarezza del codice. Se possibile, usa const per valori che non cambiano e let per quelli che cambiano, ma cerca di mantenere lo stesso tipo di dato per quella variabile.

Prossimi Passi

Ora che hai familiarità con i tipi di dato primitivi, sei pronto per esplorare strutture più complesse. Nella prossima lezione parleremo degli Oggetti e degli Array, che sono i "contenitori" che permettono di raggruppare più valori primitivi in un'unica entità.

Per approfondire, ti consiglio di:

  1. Sperimentare con l'operatore typeof su diversi valori nella console del tuo browser.
  2. Provare a creare un piccolo script che converta input testuali in numeri e gestisca l'eventuale NaN.
  3. Leggere la documentazione MDN (Mozilla Developer Network) sulla sezione "JavaScript Data Structures".