javascript Beginner 3 min

I tipi di dato in JavaScript: primitivi vs oggetti

I sette primitivi, gli oggetti, typeof e il famoso «bug» di null

· 614 parole

Ogni valore in JavaScript ha un tipo, che dice al motore «che genere di dato è» e cosa ci puoi fare. I tipi si dividono in due grandi famiglie: i primitivi (sette) e gli oggetti. Possiamo fare un parallelo con la chimica: i primitivi sono gli atomi e gli oggetti sono le molecole. Le molecole sono strutture più grandi, costruite mettendo insieme più atomi.

1. I sette primitivi

Un valore primitivo è semplice e immutabile: una volta creato non si può modificare. Eccoli, con un esempio ciascuno:

  • string testo: "Ciao"
  • number numeri interi e decimali: 42, 3.14
  • bigint interi enormi, oltre il limite sicuro di number: 42n
  • boolean vero o falso: true / false
  • undefined «nessun valore ancora assegnato» (lo mette il motore)
  • symbol un valore unico e irripetibile, usato come chiave: Symbol()
  • null «vuoto di proposito» (lo metti tu esplicitamente)

Immutabile è come il numero 5. Puoi cambiare la variabile che lo contiene (metterci 6 al posto suo), ma non puoi trasformare il 5 stesso: il 5 resta 5 per sempre. Si sostituisce il valore, non lo puoi modificare.

Fonte: MDN Web Docs: glossario «Primitive» e «JavaScript data types and data structures».

2. Gli oggetti: l'ottava famiglia

L'ottavo tipo è object: un contenitore di coppie chiave-valore. Anche gli array e le funzioni sono, sotto sotto, oggetti. A differenza dei primitivi, gli oggetti sono modificabili (mutabili).

const persona = { 
       nome: "Ada", 
       eta: 36 
}; // oggetto 

const numeri = [1, 2, 3];   // anche un array e' un oggetto

3. Copia vs riferimento: perché la distinzione conta

Non è teoria: cambia il modo in cui i valori si copiano. I primitivi si copiano per valore (nasce una copia indipendente). Gli oggetti si gestiscono per riferimento: la variabile contiene un «indirizzo» che punta all'oggetto, e due variabili possono puntare allo stesso.

let a = 5; 
let b = a;  // copia indipendente 
b = 9; 
console.log(a); // 5 (a non cambia) 
const o1 = {
     v: 1 
};
 const o2 = o1; // stesso indirizzo, stesso oggetto! 
o2.v = 99;
 console.log(o1.v); // 99 (cambiato anche o1)

Il tipo primitivo è un numero scritto su un foglietto: se lo ricopi su un secondo foglietto, hai due foglietti indipendenti. L'oggetto è l'indirizzo di una casa: se lo dai a due persone e una ridipinge le pareti, anche l'altra le vedrà ridipinte.

Fonte: MDN Web Docs: «JavaScript data types and data structures» (gli oggetti sono gli unici valori mutabili).

4. typeof: chiedere il tipo di un valore

L'operatore typeof restituisce una stringa che ti dice il tipo di un valore. Comodo per capire con che tipo di dato hai a che fare:

typeof "Ciao" // "string" 
typeof 42 //  "number" 
typeof 42n // "bigint" 
typeof true //  "boolean" 
typeof undefined // "undefined" 
typeof Symbol() // "symbol" 
typeof {} // "object" 
typeof [1, 2, 3] // "object" (anche gli array!) 
typeof function(){} // "function"

Attenzione: gli array danno "object", non «array». Per distinguerli si usa Array.isArray().

Fonte: MDN Web Docs: operatore «typeof» (tabella dei valori restituiti).

5. Il quirk di null

Ed ecco la sorpresa più famosa di JavaScript:

typeof null // "object" <- e non "null"!

Perché? È un bug storico, presente fin dalla primissima versione di JavaScript. All'epoca ogni valore era rappresentato da un'etichetta di tipo più il valore: l'etichetta degli oggetti era 0, e null era il puntatore NULL (0x00), che finiva anch'esso con l'etichetta 0 e quindi «object». Una correzione fu proposta, ma respinta per non rompere i siti esistenti: resta così per sempre.

Come si controlla allora se un valore è null? Non con typeof, ma con l'uguaglianza stretta: valore === null.

Bonus: null vs undefined: undefined significa «non ho ancora assegnato niente» (lo mette il motore da solo); null significa «vuoto di proposito» (lo metti tu). Curiosità: null == undefined è true, ma null === undefined è false (sono tipi diversi).

In sintesi

Tipo Esempio typeof restituisce
string "Ciao" "string"
number 42, 3.14 "number"
bigint 42n "bigint"
boolean true "boolean"
undefined (non assegnato) "undefined"
symbol Symbol() "symbol"
null null "object" <- quirk!
object { }, [ ] "object"

Per approfondire

Accedi o registrati per votare, salvare o commentare la pillola

Commenti (0)

Registrati per commentare, fare domande e proporre l'argomento della prossima pillola (oppure accedi se hai già un account).

Nessun commento. Sii il primo a scrivere qualcosa.

Pillole correlate