JSON è testo, non un oggetto
JSON (JavaScript Object Notation) è un formato di testo per scambiare dati. Somiglia a un oggetto letterale JavaScript, ma è una stringa: una sequenza di caratteri che puoi inviare in rete, salvare in un file o incollare in una configurazione.
// A JavaScript object - a live value in memory.
const user = { name: "Rosa", age: 30 };
// JSON - a string of text that represents the same data.
const json = '{"name":"Rosa","age":30}';
È facile confonderli perché si somigliano. Il modello mentale che ti tiene sulla strada giusta: gli oggetti vivono nel tuo programma; JSON è l'aspetto che hanno quando escono dalla porta. Passi dall'uno all'altro con due funzioni: JSON.stringify (da oggetto a stringa) e JSON.parse (da stringa a oggetto).
JSON.stringify: da oggetto a stringa
Trasforma qualsiasi valore JavaScript nella sua rappresentazione JSON:
Il risultato è una stringa su una sola riga senza spazi: compatta, ideale da inviare in rete. Il controllo con typeof lo conferma: string, non object.
Per renderla leggibile mentre fai debug, passa due argomenti in più. Il secondo è un replacer (ci arriviamo); passare null significa "includi tutto". Il terzo è l'indentazione:
È la forma standard per un output formattato. Usa 2 o 4 spazi: corrisponde a ciò che produce la maggior parte degli strumenti.
JSON.parse: da stringa a oggetto
L'operazione inversa: prendi una stringa JSON e ottieni indietro un valore JavaScript.
Una volta fatto il parsing, hai a che fare con un oggetto normale: accesso con il punto, con le parentesi quadre, metodi degli array, tutto quanto.
JSON.parse è pignolo. Tutti questi lanciano un SyntaxError:
JSON.parse("{name: 'Rosa'}"); // unquoted key, single quotes
JSON.parse('{"name": "Rosa",}'); // trailing comma
JSON.parse("// a comment\n{}"); // comments aren't allowed
JSON.parse(""); // empty string
Ogni volta che l'input arriva da fuori dal tuo programma (una risposta di fetch, un file, un input dell'utente), racchiudi il parsing in un try/catch:
Valori che non sopravvivono al viaggio di andata e ritorno
JSON supporta sei tipi di valore: stringhe, numeri, booleani, null, array e oggetti semplici. Tutto il resto in JavaScript viene eliminato, trasformato oppure genera un errore.
Cosa succede:
- Le funzioni e
undefinedvengono rimossi in silenzio dagli oggetti. Dentro gli array diventanonull: in JSON gli array non possono avere buchi. - Gli oggetti
Datevengono serializzati come stringa ISO tramite il loro metodotoJSON. Il parsing ti restituisce la stringa, non unaDate. BigIntlancia unTypeError. I numeri JSON non hanno un equivalente.Map,Sete i riferimenti circolari non funzionano nemmeno loro senza interventi.
La soluzione per il viaggio di andata e ritorno delle Date è la funzione reviver di JSON.parse:
Il reviver viene eseguito per ogni coppia chiave/valore e ti permette di trasformare i valori in entrata.
Il replacer: filtrare cosa viene serializzato
Il secondo argomento di JSON.stringify ti permette di controllare cosa finisce nell'output. Passa un array di chiavi per includere solo quelle:
Oppure passa una funzione per una logica qualsiasi: eliminare campi, mascherare valori, trasformarli al volo.
Restituire undefined rimuove la chiave. Restituire qualsiasi altro valore la sostituisce.
Personalizzare con toJSON
Se un oggetto ha un metodo toJSON, JSON.stringify lo chiama e serializza il valore restituito al suo posto. È così che Date controlla il proprio formato, e puoi usare lo stesso aggancio:
Ottimo per le classi che vogliono una forma pubblica coerente, indipendentemente da chi le serializza.
Copia profonda (il vecchio trucco e quello migliore)
Per anni, JSON.parse(JSON.stringify(obj)) è stato il modo in una riga per fare una copia profonda di un oggetto semplice:
Funziona, a patto che l'oggetto contenga solo valori compatibili con JSON. Date, Map e funzioni lo rompono tutte (vedi i problemi del viaggio di andata e ritorno qui sopra).
Il JavaScript moderno ha structuredClone, che gestisce Date, Map, Set, typed array e riferimenti circolari:
Usa structuredClone quando puoi. Tieni il trucco JSON.parse(JSON.stringify(...)) di riserva per copie veloci di dati semplici.
Un esempio realistico: fetch e parsing
Il posto in cui toccherai JSON più spesso è HTTP. fetch non fa il parsing del JSON al posto tuo: chiami .json() sulla risposta (che in pratica è JSON.parse sul corpo della risposta):
Inviare JSON è l'operazione inversa: applica JSON.stringify al corpo e imposta l'header Content-Type.
await fetch("/api/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Rosa", age: 30 }),
});
Questi due schemi coprono la stragrande maggioranza del lavoro reale con JSON.
Prossimo passo: optional chaining
Il JSON ricevuto ha spesso campi facoltativi: uno user.address.city che potrebbe non esistere, un response.data.items che potrebbe mancare. Accedere a proprietà profondamente annidate senza far crashare tutto è il compito dell'optional chaining (?.), l'argomento della prossima pagina.
Domande frequenti
Qual è la differenza tra JSON e un oggetto JavaScript?
JSON è un formato di testo: una stringa che somiglia a un oggetto letterale JavaScript ma con regole più rigide. Le chiavi devono stare tra virgolette doppie, le stringhe devono usare virgolette doppie e i valori sono limitati a stringhe, numeri, booleani, null, array e oggetti semplici. Un oggetto JavaScript è un valore vivo in memoria che può contenere funzioni, undefined, istanze di Date e qualsiasi altra cosa.
Come converto un oggetto JavaScript in JSON?
Chiama JSON.stringify(obj). Percorre l'oggetto e restituisce una stringa JSON. Passa un terzo argomento, come in JSON.stringify(obj, null, 2), per formattare l'output con un'indentazione di 2 spazi. Le funzioni e i valori undefined vengono eliminati dagli oggetti e diventano null dentro gli array.
Perché JSON.parse lancia un errore?
JSON.parse è rigido: virgole finali, apici singoli, chiavi senza virgolette e commenti causano tutti un SyntaxError. Racchiudi la chiamata in un try/catch ogni volta che l'input arriva da una richiesta di rete, da un file o da un utente, cioè ovunque la stringa possa non essere JSON valido.
JSON.stringify conserva le date?
No. Una Date diventa una stringa ISO come "2026-01-15T10:30:00.000Z". Quando la rileggi con JSON.parse, ottieni quella stringa, non un oggetto Date. Usa l'argomento reviver di JSON.parse per riconvertire le stringhe ISO in istanze di Date se ti servono.