JSON in JavaScript
Impara a lavorare con JSON in JavaScript: parse, stringify, reviver, replacer, pretty-print, deep copy, date e gli errori più comuni.
JavaScript Object Notation (JSON) è la colonna portante dello scambio di dati sul web. Quasi ogni API che chiami restituisce JSON, ogni file di configurazione che leggi è probabilmente JSON e ogni volta che il browser comunica con un server, JSON è di solito il formato trasmesso. Questa guida copre tutto ciò che ti serve per lavorare con JSON in JavaScript con sicurezza: la sintassi, i due metodi fondamentali (JSON.parse e JSON.stringify), come formattare e filtrare l'output, come gestire le date e le copie profonde, e le insidie che si presentano in produzione.
Cos'è JSON e perché è importante
JSON è un formato di dati leggero e basato su testo, semplice da leggere e scrivere per gli esseri umani e facile da analizzare e generare per le macchine. È indipendente dal linguaggio — anche se la sua sintassi è derivata da JavaScript (Standard ECMA-262), praticamente ogni linguaggio (Python, Java, C#, Go, Rust, PHP) può leggerlo e scriverlo. Questa universalità è esattamente il motivo per cui è diventato il formato predefinito per le REST API, i file di configurazione (package.json, tsconfig.json) e localStorage.
La cosa fondamentale da capire: JSON è una string, non un object. Una string JSON diventa un object JavaScript utilizzabile solo dopo averla analizzata, e un object JavaScript diventa JSON solo dopo averlo serializzato. La maggior parte del lavoro con JSON consiste nel passare tra questi due stati.
Sintassi di base di JSON
La sintassi JSON è un sottoinsieme rigoroso della sintassi letterale degli object JavaScript:
- I dati sono scritti come coppie
"chiave": valore - Le coppie sono separate da virgole
- Le parentesi graffe
{}contengono object, le parentesi quadre[]contengono array - Le chiavi devono essere string con doppi apici (le virgolette singole e le chiavi senza apici non sono valide)
- I valori possono essere string, numeri, boolean,
null, object o array — ma nonundefined, una funzione o unDate
{
"name": "John",
"age": 30,
"isDeveloper": true,
"languages": ["JavaScript", "Python", "Rust"]
}Analizzare JSON con JSON.parse()
JSON.parse() trasforma una string JSON in un object JavaScript (o array, numero, ecc.) che puoi leggere e manipolare. Nel codice reale — specialmente quando il JSON proviene da una richiesta di rete o da un input utente — racchiudilo sempre in un try...catch, perché un JSON non valido genera un SyntaxError.
Accedere ai dati annidati
Il JSON analizzato si comporta come qualsiasi altro object, quindi puoi accedere ai valori annidati con la notazione a punto o a parentesi quadre. Questa è l'operazione più comune con una risposta API.
Trasformare i valori con un reviver
JSON.parse() accetta una funzione reviver opzionale come secondo argomento. Viene chiamata per ogni coppia chiave/valore e ciò che restituisce diventa il valore finale — utile per convertire i tipi durante l'analisi. Un uso classico è il ripristino degli object Date (JSON non ha un tipo data, quindi le date arrivano come string).
Serializzare gli object con JSON.stringify()
JSON.stringify() fa l'operazione inversa: converte un valore JavaScript in una string JSON, pronta per essere inviata sulla rete o salvata in memoria.
Pretty-printing con indentazione
Il terzo argomento controlla la spaziatura. Passa un numero (spazi) o una string per produrre JSON leggibile e indentato — utile per log, file di configurazione e debug.
Filtrare le proprietà con un replacer
Il secondo argomento è un replacer. Come array di chiavi, inserisce nella whitelist le proprietà da mantenere — un modo rapido per eliminare i campi sensibili come le password prima di inviare i dati.
Come funzione, il replacer viene chiamato per ogni chiave e ti permette di trasformare o omettere valori. Restituire undefined da esso esclude quella proprietà.
Serializzazione personalizzata con toJSON
Puoi controllare come un object specifico viene serializzato fornendogli un metodo toJSON(). Quando JSON.stringify() incontra un object con questo metodo, chiama toJSON() e serializza ciò che restituisce. (È esattamente così che gli object Date producono string ISO — hanno un toJSON integrato.)
Cosa stringify omette silenziosamente
JSON.stringify() è lossy per design. Sapere cosa salta previene bug confusi:
- I valori
undefined, le funzioni e i valoriSymbolvengono omessi dagli object (e diventanonullall'interno degli array). - Gli object
Datediventano string ISO (tramite il lorotoJSON). NaNeInfinitydiventanonull.BigIntgenera unTypeError.- I riferimenti circolari generano un
TypeError.
Tecniche avanzate e pattern comuni
Oltre ai due metodi fondamentali, il lavoro quotidiano con JSON comprende la copia profonda, la gestione delle date e l'elaborazione di array di record.
Copia profonda degli object
Il trucco JSON.parse(JSON.stringify(obj)) crea una copia profonda — un clone i cui object annidati sono completamente indipendenti dall'originale, quindi modificarne uno non influisce mai sull'altro.
È rapido e senza dipendenze, ma eredita tutti i limiti di stringify: elimina funzioni, undefined e Symbol, trasforma i Date in string e genera errori con i riferimenti circolari. Per un clone fedele, preferisci il built-in structuredClone(), che gestisce date, mappe, set e cicli.
Lavorare con le date
JSON non ha un tipo data, quindi le date vengono trasmesse come string ISO 8601. JSON.stringify le scrive automaticamente, ma durante il parse ottieni una string normale — devi ricostruire il Date manualmente, con new Date(...) o un reviver (mostrato in precedenza).
Elaborare array di record
Le risposte API sono solitamente array di object. Dopo l'analisi, i metodi standard degli array (forEach, map, filter) fanno il resto.
JSON e il browser: fetch e localStorage
Due contesti quotidiani in cui JSON è presente:
fetch:response.json()legge il corpo e lo analizza per te, quindi raramente chiameraiJSON.parsedirettamente su un risultato fetch —const data = await response.json();. Vedi la guida alla Fetch API.localStorage: memorizza solo string, quindi serializza all'ingresso e analizza all'uscita:localStorage.setItem('user', JSON.stringify(user))poiJSON.parse(localStorage.getItem('user')).
Conclusione
JSON è il formato che userai più spesso come sviluppatore JavaScript e si riduce essenzialmente a due metodi: JSON.parse() per trasformare una string in un valore utilizzabile, e JSON.stringify() per trasformare un valore in una string. Aggiungi gli argomenti reviver e replacer per la conversione dei tipi e il filtraggio, l'indentazione per un output leggibile, e toJSON per la serializzazione personalizzata, e potrai gestire quasi qualsiasi attività di scambio dati.
Tieni a mente i casi limite lossy — undefined/funzioni eliminate, date serializzate come string ed errori di riferimento circolare — e usa structuredClone() quando hai bisogno di una vera copia anziché di un ciclo JSON. Con questi strumenti puoi spostare i dati con sicurezza tra la tua applicazione, il server e la memoria del browser.