← Tutti gli articoli

Come serializzare JSON con JSON.stringify

JSON.stringify converte un valore in stringa JSON. Scopri gli argomenti space e replacer, il hook toJSON, e i valori che omette o genera errori.

JSON.stringify() converte un valore JavaScript in una stringa JSON —— per inviarlo nel body di una richiesta, salvarlo in un file o riporlo in localStorage. Sembra semplice, ma i suoi tre argomenti, la gestione dei valori speciali e l'hook toJSON fanno inciampare gli sviluppatori in continuazione. Questa guida copre tutto ciò che fa JSON.stringify(), gli equivalenti in altri linguaggi e le trappole da evitare.

Cosa fa JSON.stringify

Percorre un valore in modo ricorsivo e produce una stringa JSON conforme alla spec. L'output di default è compatto, senza spazi extra:

const user = { name: "Ada", age: 36, active: true };

JSON.stringify(user);
// '{"name":"Ada","age":36,"active":true}'

Poiché emette sempre JSON valido, non costruire mai stringhe JSON a mano con concatenazione o template literal —— farlo è la causa numero uno di errori [object Object] e errori di virgole finali.

I tre argomenti

JSON.stringify(value, replacer, space) accetta un valore più due argomenti opzionali che quasi nessuno usa —— ma sono potenti.

space —— pretty-print

Il terzo argomento controlla l'indentazione. Passa un numero per quegli spazi, o una stringa come '\t' per tabulazioni:

JSON.stringify(user, null, 2);
// {
//   "name": "Ada",
//   "age": 36,
//   "active": true
// }

È così che si fa pretty-print di JSON nel codice —— vedi Come formattare JSON. Ometti l'argomento (o passa 0) per minificare; vedi Come minificare JSON.

replacer —— filtrare e trasformare

Il secondo argomento può essere un array di chiavi da includere o una funzione che trasforma ogni valore:

// Whitelist: solo queste chiavi sopravvivono
JSON.stringify(user, ['name', 'active']);
// '{"name":"Ada","active":true}'

// Funzione: maschera un campo, scarta un altro
JSON.stringify(
  { name: "Ada", password: "secret", token: "abc" },
  (key, value) => {
    if (key === 'password') return '[REDACTED]';
    if (key === 'token') return undefined; // restituire undefined omette la chiave
    return value;
  },
);
// '{"name":"Ada","password":"[REDACTED]"}'

L'hook toJSON

Se un valore ha un metodo toJSON(), JSON.stringify() lo chiama e serializza al suo posto il valore restituito. È così che gli oggetti Date diventano automaticamente stringhe ISO:

JSON.stringify({ when: new Date('2026-05-24T00:00:00Z') });
// '{"when":"2026-05-24T00:00:00.000Z"}'  ← Date.prototype.toJSON eseguito

// Definisci il tuo toJSON per serializzazione custom
class Money {
  constructor(cents) { this.cents = cents; }
  toJSON() { return (this.cents / 100).toFixed(2); }
}
JSON.stringify({ price: new Money(1999) });
// '{"price":"19.99"}'

Cosa viene scartato o convertito

JSON ha solo sei tipi, quindi i valori JavaScript senza equivalente JSON vengono silenziosamente scartati o convertiti —— fonte comune di bug nei round-trip:

Valore JavaScript Risultato di JSON.stringify
undefined (in oggetto) chiave omessa
undefined (in array) null
funzione omessa (oggetto) / null (array)
Symbol omesso
NaN, Infinity null
Date stringa ISO (via toJSON)
BigInt lancia TypeError

Per l'elenco completo di come JSON differisce dagli oggetti JavaScript, vedi JSON vs oggetti JavaScript.

Trappole comuni

I riferimenti circolari lanciano

const a = {};
a.self = a;
JSON.stringify(a);
// TypeError: Converting circular structure to JSON

// Correzione: un replacer che traccia oggetti visti, o ristruttura i dati

BigInt non è supportato

JSON.stringify({ id: 9007199254740993n });
// TypeError: Do not know how to serialize a BigInt

// Correzione: converti in stringa prima, o aggiungi un replacer
JSON.stringify({ id: 9007199254740993n }, (k, v) =>
  typeof v === 'bigint' ? v.toString() : v
);

Gli interi grandi perdono precisione nel round-trip

I numeri oltre 253 non possono essere rappresentati esattamente. Se fai stringify e poi parse di un ID intero grande, può cambiare. Conserva tali ID come stringhe.

API vicine: structuredClone, il reviver e Stable Stringify

  • structuredClone —— per copie profonde in memoria, non usare JSON.parse(JSON.stringify(x)). structuredClone gestisce Date, Map, Set, ArrayBuffer e riferimenti circolari in modo nativo ed è molto più veloce.
  • L'argomento reviver di JSON.parse è lo specchio del replacer di qui. Usali in coppia per round-trip senza perdita su tipi che JSON non modella —— es. codifica Date come stringa ISO nel replacer e reidratala nel reviver.
  • Librerie di stable-stringify (es. json-stable-stringify, fast-json-stable-stringify) —— producono la stessa stringa indipendentemente dall'ordine di inserimento delle chiavi. Usale quando l'output viene hashato, firmato o confrontato come testo (vedi RFC 8785 / JCS per la versione formale).

Stringify in altri linguaggi

# Python
import json
json.dumps({"name": "Ada"})                       # compatto
json.dumps({"name": "Ada"}, indent=2)             # pretty
json.dumps({"name": "Ada"}, separators=(',', ':')) # minificato

// Go
import "encoding/json"
b, _ := json.Marshal(map[string]string{"name": "Ada"})

// Ruby
require 'json'
{ name: "Ada" }.to_json

Stringify di JSON nel tuo browser

Devi fare escape di un valore JSON in un literal di stringa —— per incorporarlo in codice, in una colonna di DB o in un comando shell? Lo strumento JSON Stringify di fixjson lo fa all'istante, nel tuo browser, senza inviare dati a nessun server.

Domande frequenti

Come faccio pretty-print con JSON.stringify?

Passa un terzo argomento: JSON.stringify(value, null, 2) per 2 spazi o '\t' per tabulazioni. Vedi Come formattare JSON.

Perché JSON.stringify scarta alcune delle mie proprietà?

Le proprietà con valori undefined, funzione o Symbol vengono omesse perché JSON non ha rappresentazione per loro. Usa un replacer o convertile prima.

Come faccio stringify di un valore con BigInt?

JSON.stringify() lancia su BigInt. Fornisci un replacer che chiami .toString() sui bigint e parsali deliberatamente dall'altra parte.

Qual è la differenza tra JSON.stringify e JSON.parse?

stringify trasforma un valore in una stringa JSON; parse trasforma una stringa JSON in un valore. Sono inversi. Per le trappole del parsing, vedi Gestire JSON rotto in JavaScript.

Come faccio JSON.stringify di un Map o Set?

Di default entrambi serializzano come "{}" —— una Map non ha proprietà proprie enumerabili e un Set stringifica come oggetto vuoto. Convertili prima in una forma JSON-friendly (o tramite un replacer):

// Map → array di coppie [key, value] (round-trippable)
JSON.stringify([...myMap]);
// o con un replacer:
JSON.stringify({ data: myMap }, (k, v) =>
  v instanceof Map ? Object.fromEntries(v) :
  v instanceof Set ? [...v] : v
);

Sulla strada del ritorno, ricostruisci con new Map(arr) / new Set(arr) in un reviver di JSON.parse, dato che il JSON puro non ha tipi Map/Set.

Provalo ora

Fonti

Ultima revisione: giugno 2026.