JSON Formatter JavaScript — JSON.stringify()
Usa il Formattatore e Abbellitore JSON gratuito direttamente nel tuo browser — nessuna installazione.
Prova Formattatore e Abbellitore JSON online →Quando faccio il debug delle risposte API in Node.js, un muro di JSON minificato è la prima cosa che mi rallenta — una chiamata a JSON.stringify(data, null, 2) e la struttura diventa immediatamente leggibile. Per formattare JSON in JavaScript, non serve nulla oltre al runtime stesso: JSON.stringify è integrato in tutti i browser e in Node.js, senza alcuna installazione. Se hai bisogno solo di un risultato rapido senza scrivere codice, il Formattatore JSON di ToolDeck lo fa istantaneamente. Questa guida copre tutto il necessario: il parametro space, array e funzioni replacer, la gestione di Date, BigInte riferimenti circolari, la lettura e scrittura di file JSON in Node.js (18+), la formattazione da riga di comando, e la libreria fast-json-stringify per la serializzazione in produzione.
- ✓JSON.stringify(data, null, 2) è integrato in tutti i browser e Node.js — senza installazione.
- ✓Il parametro replacer accetta un array (elenco di chiavi) o una funzione (trasformare valori) — usalo per mascherare i campi sensibili.
- ✓Gli oggetti Date si serializzano automaticamente tramite toJSON() → stringa ISO 8601; BigInt lancia TypeError e richiede un replacer personalizzato.
- ✓I riferimenti circolari lanciano TypeError — risolvili con un Set seen in una funzione replacer, o usa la libreria flatted.
- ✓Per la formattazione da CLI usa node -p "JSON.stringify(require('./file.json'),null,2)" — senza strumenti aggiuntivi.
Cos'è la formattazione JSON?
La formattazione JSON (detta anche pretty-printing) trasforma una stringa JSON compatta e minificata in una presentazione leggibile con indentazione coerente e interruzioni di riga. I dati sottostanti sono identici — cambia solo lo spazio bianco. Il JSON compatto è ottimale per il trasferimento in rete dove ogni byte conta; il JSON formattato è ottimale per il debug, la code review e l'ispezione dei log. La funzione JSON.stringify() di JavaScript gestisce entrambi con una singola chiamata variando il parametro space.
{"orderId":"ord_8f2a91bc","status":"shipped","items":[{"sku":"HDMI-4K-2M","qty":2,"unitPrice":12.99}],"total":25.98}{
"orderId": "ord_8f2a91bc",
"status": "shipped",
"items": [
{
"sku": "HDMI-4K-2M",
"qty": 2,
"unitPrice": 12.99
}
],
"total": 25.98
}JSON.stringify() — Il formattatore integrato
JSON.stringify() è una funzione globale in ogni ambiente JavaScript — browser, Node.js, Deno, Bun — senza import necessario. Il suo terzo argomento, space, controlla l'indentazione: passa un numero per altrettanti spazi per livello, o la stringa '\t' per le tabulazioni. Ometterlo (o passare null) produce un output compatto su una sola riga.
const serverConfig = {
host: "api.payments.internal",
port: 8443,
workers: 4,
tls: { enabled: true, cert: "/etc/ssl/certs/api.pem" },
rateLimit: { requestsPerMinute: 1000, burst: 50 }
}
console.log(JSON.stringify(serverConfig, null, 2))
// {
// "host": "api.payments.internal",
// "port": 8443,
// "workers": 4,
// "tls": {
// "enabled": true,
// "cert": "/etc/ssl/certs/api.pem"
// },
// "rateLimit": {
// "requestsPerMinute": 1000,
// "burst": 50
// }
// }Il parametro space accetta un numero (1–10 spazi) o una stringa. Passare un carattere di tabulazione produce un output che molti editor e strumenti di diff preferiscono. Si possono anche combinare tutti e tre i parametri — ecco un pattern reale che uso quando scrivo JSON formattato nei file di configurazione:
const telemetryEvent = {
eventId: "evt_3c7f9a2b",
service: "checkout-api",
severity: "warn",
latencyMs: 342,
region: "eu-west-1",
tags: ["payment", "timeout", "retry"]
}
// Indentazione 2 spazi (la più comune nei progetti JS)
JSON.stringify(telemetryEvent, null, 2)
// Indentazione con tabulazione (preferita da alcuni linter e strumenti di config)
JSON.stringify(telemetryEvent, null, '\t')
// Compatto — senza spazi bianchi (per il trasferimento in rete)
JSON.stringify(telemetryEvent)
// {"eventId":"evt_3c7f9a2b","service":"checkout-api",...}undefined, le funzioni e i valori Symbol vengono silenziosamente omessi dall'output. Se il valore di una proprietà è undefined, quella chiave non apparirà affatto nella stringa serializzata — è una fonte comune di bug quando si registrano oggetti con campi opzionali.Funzioni replacer — Filtrare e trasformare l'output
Il secondo argomento di JSON.stringify() è il replacer. Si presenta in due forme: un array che elenca le chiavi consentite, o una funzione chiamata per ogni coppia chiave/valore che può filtrare, trasformare o oscurare i valori. Uso la forma array quando ho bisogno di un sottoinsieme rapido, e la forma funzione quando devo mascherare dati sensibili prima del logging.
Replacer array — Elenco di chiavi specifiche
const order = {
orderId: "ord_8f2a91bc",
customer: {
id: "usr_4421",
email: "m.rossi@esempio.it",
passwordHash: "bcrypt:$2b$12$XKzV..."
},
items: [{ sku: "HDMI-4K-2M", qty: 2, unitPrice: 12.99 }],
createdAt: "2026-03-10T14:22:00Z"
}
// Includere solo i campi sicuri nel log
const safeLog = JSON.stringify(order, ["orderId", "items", "createdAt"], 2)
// {
// "orderId": "ord_8f2a91bc",
// "items": [{ "sku": "HDMI-4K-2M", "qty": 2, "unitPrice": 12.99 }],
// "createdAt": "2026-03-10T14:22:00Z"
// }
// passwordHash e customer.email vengono esclusiReplacer funzione — Trasformare i valori
const auditRecord = {
requestId: "req_7d2e91",
user: { id: "usr_4421", email: "m.rossi@esempio.it", apiKey: "sk-live-eKx9..." },
action: "update_billing",
timestamp: new Date("2026-03-10T14:22:00Z"),
durationMs: 87
}
function safeReplacer(key, value) {
// Oscurare i campi che sembrano segreti o dati personali
if (key === "apiKey") return "[OSCURATO]"
if (key === "email") return value.replace(/(?<=.{2}).+(?=@)/, "***")
return value
}
console.log(JSON.stringify(auditRecord, safeReplacer, 2))
// {
// "requestId": "req_7d2e91",
// "user": { "id": "usr_4421", "email": "m.***@esempio.it", "apiKey": "[OSCURATO]" },
// "action": "update_billing",
// "timestamp": "2026-03-10T14:22:00.000Z",
// "durationMs": 87
// }this impostato sull'oggetto contenente la chiave corrente. La primissima chiamata passa una stringa vuota come chiave e l'intero valore in fase di serializzazione — restituiscilo invariato per procedere con la serializzazione normale.Gestire i tipi non serializzabili
Non tutti i valori JavaScript si mappano correttamente su JSON. Conoscere il comportamento di ogni tipo evita la perdita silenziosa di dati e gli errori inattesi nel codice di produzione.
Date — Automatico tramite toJSON()
Gli oggetti Date implementano un metodo toJSON() che restituisce una stringa ISO 8601. JSON.stringify() chiama toJSON() automaticamente prima della serializzazione, quindi non è necessaria alcuna gestione personalizzata.
const webhook = {
eventType: "payment.succeeded",
occurredAt: new Date("2026-03-10T14:22:00Z"),
processedAt: new Date()
}
JSON.stringify(webhook, null, 2)
// {
// "eventType": "payment.succeeded",
// "occurredAt": "2026-03-10T14:22:00.000Z",
// "processedAt": "2026-03-10T14:22:01.347Z"
// }
// Qualsiasi oggetto con un metodo toJSON() riceve lo stesso trattamento:
const custom = { toJSON: () => "valore-personalizzato", hidden: 42 }
JSON.stringify(custom) // '"valore-personalizzato"'Classi personalizzate — Implementare toJSON()
Qualsiasi classe può implementare un metodo toJSON() e JSON.stringify() lo chiamerà automaticamente durante la serializzazione. Questo approccio è più pulito di un replacer globale per i tipi di dominio che compaiono in tutto il codice.
class Money {
constructor(amount, currency) {
this.amount = amount
this.currency = currency
}
toJSON() {
// Chiamato automaticamente da JSON.stringify
return { amount: this.amount, currency: this.currency, formatted: `${this.currency} ${this.amount.toFixed(2)}` }
}
}
class OrderId {
constructor(id) { this.id = id }
toJSON() { return this.id } // Serializzare come stringa semplice
}
const invoice = {
invoiceId: new OrderId('inv_8f2a91bc'),
subtotal: new Money(199.00, 'EUR'),
tax: new Money(15.92, 'EUR'),
issuedAt: new Date('2026-03-10T14:22:00Z')
}
JSON.stringify(invoice, null, 2)
// {
// "invoiceId": "inv_8f2a91bc",
// "subtotal": { "amount": 199, "currency": "EUR", "formatted": "EUR 199.00" },
// "tax": { "amount": 15.92, "currency": "EUR", "formatted": "EUR 15.92" },
// "issuedAt": "2026-03-10T14:22:00.000Z"
// }toJSON() ha la priorità sulla funzione replacer. Se entrambi sono presenti, toJSON() viene eseguito prima — il replacer riceve il valore già convertito, non l'istanza della classe originale.BigInt — TypeError senza un replacer
// Questo lancia: TypeError: Do not know how to serialize a BigInt
// JSON.stringify({ sessionId: 9007199254741234n })
// Soluzione: convertire BigInt in stringa nel replacer
function bigIntReplacer(_key, value) {
return typeof value === 'bigint' ? value.toString() : value
}
const metrics = {
requestCount: 9007199254741234n, // supera Number.MAX_SAFE_INTEGER
service: "ingestion-worker",
region: "eu-west-1"
}
JSON.stringify(metrics, bigIntReplacer, 2)
// {
// "requestCount": "9007199254741234",
// "service": "ingestion-worker",
// "region": "eu-west-1"
// }Riferimenti circolari — TypeError senza un Set seen
// Questo lancia: TypeError: Converting circular structure to JSON
// const node = { id: "n1" }; node.self = node; JSON.stringify(node)
// Soluzione: tenere traccia degli oggetti visti con un WeakSet
function circularReplacer() {
const seen = new WeakSet()
return function (_key, value) {
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) return '[Circular]'
seen.add(value)
}
return value
}
}
const parent = { id: "node_parent", label: "root" }
const child = { id: "node_child", parent }
parent.child = child // circolare
JSON.stringify(parent, circularReplacer(), 2)
// {
// "id": "node_parent",
// "label": "root",
// "child": { "id": "node_child", "parent": "[Circular]" }
// }
// Alternativa: npm install flatted
// import { stringify } from 'flatted'
// stringify(parent) // gestisce i riferimenti circolari nativamenteRiferimento dei parametri di JSON.stringify()
Tutti e tre i parametri sono ben supportati in ogni runtime JavaScript moderno. I valori predefiniti producono JSON compatto su una riga — passa i parametri esplicitamente per ottenere un output leggibile.
Formattare JSON da un file e da una risposta API
In Node.js (18+) spesso è necessario riformattare un file di configurazione JSON o visualizzare in modo leggibile una risposta API per il debug. Entrambi i pattern usano lo stesso approccio in due fasi: analizzare il testo grezzo con JSON.parse() e poi riseriallizzare con JSON.stringify().
Leggere e riscrivere un file di configurazione JSON
import { readFileSync, writeFileSync } from 'fs'
try {
const raw = readFileSync('./config/database.json', 'utf8')
const config = JSON.parse(raw)
writeFileSync('./config/database.json', JSON.stringify(config, null, 2))
console.log('Config riformattato con successo')
} catch (err) {
console.error('Errore nella riformattazione del config:', err.message)
// JSON.parse lancia SyntaxError se il file contiene JSON non valido
// readFileSync lancia ENOENT se il file non esiste
}Riformattazione asincrona di file (fs/promises)
import { readFile, writeFile } from 'fs/promises'
async function reformatJson(filePath) {
const raw = await readFile(filePath, 'utf8')
const parsed = JSON.parse(raw)
const formatted = JSON.stringify(parsed, null, 2)
await writeFile(filePath, formatted, 'utf8')
return { keys: Object.keys(parsed).length }
}
// Utilizzo
const { keys } = await reformatJson('./config/feature-flags.json')
console.log(`Riformattate ${keys} chiavi di primo livello`)Visualizzare in formato leggibile il JSON da una risposta fetch()
Quando si costruisce o si fa debug di un client API in Node.js 18+ o nel browser, formattare il corpo della risposta è il modo più rapido per capire cosa ha restituito il server. Il pattern standard è response.json() (oggetto analizzato) passato a JSON.stringify(). Se hai bisogno della stringa grezza prima — per esempio per calcolare un hash o registrarla verbatim — usa response.text() poi JSON.parse().
// Pattern 1: response.json() → visualizzare in formato leggibile
async function debugEndpoint(url) {
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.API_TOKEN}` }
})
if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`)
const data = await res.json()
console.log(JSON.stringify(data, null, 2))
}
await debugEndpoint('https://api.stripe.com/v1/charges?limit=3')// Pattern 2: response.text() → analizzare → formattare
// Utile quando si vuole registrare la risposta grezza E visualizzarla formattata
async function inspectRawResponse(url) {
const res = await fetch(url)
const raw = await res.text()
console.log('Lunghezza della risposta grezza:', raw.length)
try {
const parsed = JSON.parse(raw)
console.log('Formattato:')
console.log(JSON.stringify(parsed, null, 2))
} catch {
console.error('La risposta non è JSON valido:', raw.slice(0, 200))
}
}Formattazione da riga di comando
Node.js include capacità sufficienti per formattare JSON dal terminale senza strumenti aggiuntivi. Questi one-liner sono utili negli script CI, nelle pipeline di deploy e negli alias di shell. Per un uso interattivo ancora più rapido, installa jq — lo standard de facto per la manipolazione JSON da riga di comando.
# Formattare package.json usando node -p (print)
node -p "JSON.stringify(require('./package.json'), null, 2)"
# Formattare dallo stdin (compatibile con pipe, funziona in CI)
echo '{"port":3000,"env":"production"}' | node -e "
const d = require('fs').readFileSync(0, 'utf8')
console.log(JSON.stringify(JSON.parse(d), null, 2))
"
# Formattare una risposta API salvata in un file
cat api-response.json | node -e "
process.stdin.setEncoding('utf8')
let s = ''
process.stdin.on('data', c => s += c)
process.stdin.on('end', () => console.log(JSON.stringify(JSON.parse(s), null, 2)))
"# Alternativa Python (preinstallato su macOS e la maggior parte dei Linux)
cat api-response.json | python3 -m json.tool
# jq — più veloce e ricco di funzionalità (brew install jq / apt install jq)
cat api-response.json | jq .
# jq — formattare e filtrare in un solo passaggio
cat api-response.json | jq '.data.users[] | {id, email}'"type": "module" nel package.json), require() non è disponibile nei one-liner. Usa --input-type=module e fs.readFileSync in alternativa, oppure passa a node -e con un frammento CommonJS come mostrato sopra.Se non sei affatto nel terminale — stai incollando una risposta Postman o un file di log — il Formattatore JSON di ToolDeck ti permette di incollare, formattare e copiare in un solo passaggio con evidenziazione della sintassi e validazione integrata.
Alternativa ad alte prestazioni — fast-json-stringify
fast-json-stringify genera una funzione di serializzazione dedicata a partire da un JSON Schema. Poiché conosce in anticipo la struttura dei dati, può saltare la verifica dei tipi e usare la concatenazione di stringhe invece della discesa ricorsiva — i benchmark mostrano tipicamente un miglioramento del throughput di 2–5× rispetto a JSON.stringify() su payload grandi e ripetitivi. La uso nelle route API ad alta frequenza dove il costo di serializzazione emerge nelle trace del profiler.
npm install fast-json-stringify
import fastJson from 'fast-json-stringify'
const serializeTelemetryEvent = fastJson({
title: 'TelemetryEvent',
type: 'object',
properties: {
eventId: { type: 'string' },
service: { type: 'string' },
severity: { type: 'string', enum: ['info', 'warn', 'error'] },
latencyMs: { type: 'integer' },
timestamp: { type: 'string' },
region: { type: 'string' }
},
required: ['eventId', 'service', 'severity', 'latencyMs', 'timestamp']
})
const event = {
eventId: 'evt_3c7f9a2b',
service: 'checkout-api',
severity: 'warn',
latencyMs: 342,
timestamp: new Date().toISOString(),
region: 'eu-west-1'
}
const json = serializeTelemetryEvent(event)
// '{"eventId":"evt_3c7f9a2b","service":"checkout-api","severity":"warn",...}'fast-json-stringify è progettato per la serializzazione in produzione di dati strutturati — produce sempre output compatto (senza pretty-printing). Per un output leggibile durante lo sviluppo, usa JSON.stringify(data, null, 2) normalmente.Output nel terminale con evidenziazione della sintassi
La funzione integrata di Node.js util.inspect() produce un output colorato e leggibile, ottimizzato per la visualizzazione nel terminale. Gestisce i riferimenti circolari e BigInt nativamente, e renderizza ricorsivamente gli oggetti annidati a qualsiasi profondità. L'output non è JSON valido — usa la sintassi JavaScript (es. true invece di true, ma renderizza funzioni e Symbol invece di ometterli), il che la rende ideale per gli script di debug in Node.js ma inadatta alle risposte API o all'output su file.
import { inspect } from 'util'
const payload = {
requestId: "req_7d2e91",
user: { id: "usr_4421", roles: ["admin", "billing"] },
metadata: { ipAddress: "203.0.113.42", userAgent: "Mozilla/5.0" },
createdAt: new Date()
}
// depth: null → espandere tutti i livelli annidati; colors: true → colori ANSI nel terminale
console.log(inspect(payload, { colors: true, depth: null }))util.inspect() per JSON scritto su file, inviato in rete o archiviato in un database. Il suo output non è JSON valido e causerà errori di parsing in qualsiasi sistema a valle che chiami JSON.parse() su di esso. Riservalo esclusivamente al debug interattivo nel terminale.Lavorare con file JSON di grandi dimensioni
JSON.parse() carica l'intero file in memoria prima di analizzarlo — adatto per payload piccoli, ma impraticabile per file superiori a 50–100 MB come export di database, dump dei log applicativi o batch di analisi. Per questi casi, gli Stream di Node.js e la libreria stream-json consentono di elaborare i record uno alla volta senza saturare l'heap.
Parsing in streaming con stream-json
npm install stream-json
import { pipeline } from 'stream/promises'
import { createReadStream } from 'fs'
import { parser } from 'stream-json'
import { streamArray } from 'stream-json/streamers/StreamArray.js'
// events.json = array di milioni di oggetti — mai caricato completamente in memoria
await pipeline(
createReadStream('./events.json'),
parser(),
streamArray(),
async function* (source) {
for await (const { value: event } of source) {
if (event.severity === 'error') {
console.log(JSON.stringify(event, null, 2))
}
}
}
)NDJSON / JSON Lines — Senza dipendenze aggiuntive
NDJSON (Newline Delimited JSON) memorizza un oggetto JSON per riga ed è comune negli export di Kafka, nelle uscite di BigQuery e nelle pipeline di log strutturati. Il modulo integrato readline di Node.js lo gestisce senza pacchetti di terze parti.
import { createReadStream } from 'fs'
import { createInterface } from 'readline'
// Formato: un oggetto JSON per riga (log, export Kafka, BigQuery)
const rl = createInterface({
input: createReadStream('./logs.ndjson'),
crlfDelay: Infinity
})
for await (const line of rl) {
if (!line.trim()) continue
const entry = JSON.parse(line)
if (entry.level === 'error') {
console.log(JSON.stringify(entry, null, 2))
}
}JSON.parse() allo streaming quando il file JSON supera i 50–100 MB o quando si elabora uno stream illimitato (Kafka, pipeline di log). Per NDJSON / JSON Lines, usa readline — non richiede dipendenze aggiuntive.Errori comuni
Questi quattro errori compaiono ripetutamente nelle code review e nei report di bug in produzione. Ognuno coinvolge un comportamento sottile di JSON.stringify() che è facile da non notare e difficile da debuggare in seguito.
Problema: Le proprietà di un oggetto con valori undefined vengono omesse completamente dall'output JSON — senza avvisi né errori. Questo causa una perdita invisibile di dati quando esistono campi opzionali nell'oggetto.
Soluzione: Usa null per i valori intenzionalmente assenti che devono apparire nell'output serializzato. Riserva undefined solo per i campi che devono essere esclusi dal JSON.
const userProfile = {
userId: "usr_4421",
displayName: "Marco Rossi",
avatarUrl: undefined, // sparirà silenziosamente
bio: undefined // sparirà silenziosamente
}
JSON.stringify(userProfile, null, 2)
// { "userId": "usr_4421", "displayName": "Marco Rossi" }
// avatarUrl e bio sono spariti — senza avvisoconst userProfile = {
userId: "usr_4421",
displayName: "Marco Rossi",
avatarUrl: null, // esplicitamente assente — appare nell'output
bio: null // esplicitamente assente — appare nell'output
}
JSON.stringify(userProfile, null, 2)
// {
// "userId": "usr_4421",
// "displayName": "Marco Rossi",
// "avatarUrl": null,
// "bio": null
// }Problema: Passare un valore BigInt a JSON.stringify() lancia un TypeError a runtime. È un crash totale, non un'omissione silenziosa — si manifesterà in produzione se un campo numerico supera Number.MAX_SAFE_INTEGER.
Soluzione: Usa una funzione replacer che converte i valori BigInt in stringhe prima della serializzazione. In alternativa, converti BigInt in string o Number nel livello dati prima di passarlo a JSON.stringify.
const session = {
sessionId: 9007199254741234n, // letterale BigInt
userId: "usr_4421",
startedAt: "2026-03-10T14:00:00Z"
}
JSON.stringify(session, null, 2)
// Uncaught TypeError: Do not know how to serialize a BigIntfunction bigIntReplacer(_key, value) {
return typeof value === 'bigint' ? value.toString() : value
}
const session = {
sessionId: 9007199254741234n,
userId: "usr_4421",
startedAt: "2026-03-10T14:00:00Z"
}
JSON.stringify(session, bigIntReplacer, 2)
// {
// "sessionId": "9007199254741234",
// "userId": "usr_4421",
// "startedAt": "2026-03-10T14:00:00Z"
// }Problema: Gli oggetti che si riferiscono a se stessi — comuni negli alberi DOM, nelle liste concatenate e in alcuni risultati di ORM — lanciano un TypeError quando vengono passati a JSON.stringify(). L'errore si verifica solo al momento della serializzazione, spesso lontano da dove è stato creato il riferimento circolare.
Soluzione: Usa una funzione replacer con un WeakSet per rilevare e sostituire i riferimenti circolari, o installa la libreria flatted come sostituto diretto che gestisce nativamente le strutture circolari.
const dept = { id: "dept_eng", name: "Ingegneria" }
const team = { id: "team_frontend", dept }
dept.teams = [team] // circolare: dept → team → dept
JSON.stringify(dept, null, 2)
// Uncaught TypeError: Converting circular structure to JSONimport { stringify } from 'flatted' // npm install flatted
const dept = { id: "dept_eng", name: "Ingegneria" }
const team = { id: "team_frontend", dept }
dept.teams = [team]
// flatted gestisce i riferimenti circolari — nota: l'output è nel formato flatted, non JSON standard
stringify(dept)
// Oppure usa un replacer basato su WeakSet per JSON standard:
function circularReplacer() {
const seen = new WeakSet()
return (_key, value) => {
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) return '[Circular]'
seen.add(value)
}
return value
}
}
JSON.stringify(dept, circularReplacer(), 2)Problema: Passare un valore space maggiore di 10 a JSON.stringify() non lancia un errore — il valore viene silenziosamente limitato a 10. Gli sviluppatori che si aspettano 20 spazi per livello di indentazione per strutture profonde otterranno solo 10, generando una formattazione inaspettata nei file generati.
Soluzione: L'indentazione massima è 10 spazi. Per le strutture profonde, preferire un'indentazione di 2 spazi (la convenzione più comune nei progetti JavaScript) e affidarsi agli editor con piegatura per la navigazione.
const deepConfig = { server: { tls: { certs: { primary: "/etc/ssl/api.pem" } } } }
// Si aspetta un'indentazione di 20 spazi — ma space è limitato a 10
JSON.stringify(deepConfig, null, 20)
// Stesso output di JSON.stringify(deepConfig, null, 10)
// Nessun errore, nessun avviso — troncato silenziosamenteconst deepConfig = { server: { tls: { certs: { primary: "/etc/ssl/api.pem" } } } }
// Usare 2 (la maggior parte dei progetti) o 4 spazi — non superare mai 10
JSON.stringify(deepConfig, null, 2)
// {
// "server": {
// "tls": {
// "certs": {
// "primary": "/etc/ssl/api.pem"
// }
// }
// }
// }JSON.stringify vs alternative — Confronto rapido
Situazioni diverse richiedono strumenti diversi. JSON.stringify con un replacer copre la maggior parte dei casi d'uso in produzione senza dipendenze. util.inspect è la scelta giusta per il debug rapido nel terminale quando hai bisogno di output colorato e non hai bisogno di JSON valido. fast-json-stringify vale l'investimento nelle route ad alto throughput dove il profiling mostra un costo di serializzazione; per tutto il resto, il peso della manutenzione dello schema non vale la pena.
Domande frequenti
Come formatto JSON con indentazione in JavaScript?
Chiama JSON.stringify(data, null, 2) — il terzo argomento controlla l'indentazione. Passa 2 o 4 per gli spazi, o "\t" per le tabulazioni. Non è necessaria alcuna importazione o installazione: JSON è un oggetto globale in ogni ambiente JavaScript, inclusi browser e Node.js.
const config = { host: "api.payments.internal", port: 8443, tls: true }
console.log(JSON.stringify(config, null, 2))
// {
// "host": "api.payments.internal",
// "port": 8443,
// "tls": true
// }Cosa fa il parametro `space` in JSON.stringify()?
Il parametro space controlla l'indentazione nell'output. Passa un numero (1–10) per altrettanti spazi per livello, o una stringa come "\t" per usare un carattere di tabulazione. I valori superiori a 10 vengono silenziosamente limitati a 10. Passare null, 0 o omettere il parametro produce un JSON compatto su una sola riga.
const data = { service: "payments", version: 3, active: true }
JSON.stringify(data, null, 2) // indentazione 2 spazi
JSON.stringify(data, null, 4) // indentazione 4 spazi
JSON.stringify(data, null, '\t') // indentazione con tabulazione
JSON.stringify(data) // compatto: {"service":"payments","version":3,"active":true}Perché JSON.stringify() restituisce undefined per alcuni valori?
JSON.stringify omette silenziosamente le proprietà di oggetti i cui valori sono undefined, funzioni o Symbol — questi tipi non hanno una rappresentazione JSON. Se il valore di primo livello è undefined, la funzione restituisce undefined (non la stringa "undefined"). Usa null al posto di undefined per i campi opzionali che devono apparire nell'output.
const event = {
traceId: "tr_9a2f",
handler: () => {}, // funzione — omessa
requestId: undefined, // undefined — omesso
sessionId: Symbol("s"), // Symbol — omesso
status: "ok"
}
JSON.stringify(event, null, 2)
// { "traceId": "tr_9a2f", "status": "ok" }Come gestisco gli oggetti Date nella formattazione JSON?
Gli oggetti Date dispongono di un metodo toJSON() integrato che restituisce una stringa ISO 8601, quindi JSON.stringify li gestisce automaticamente. Non è necessario un replacer personalizzato per le date — il valore serializzato sarà una stringa come "2026-03-10T14:22:00.000Z".
const order = {
orderId: "ord_8f2a91bc",
placedAt: new Date("2026-03-10T14:22:00Z"),
total: 42.98
}
JSON.stringify(order, null, 2)
// {
// "orderId": "ord_8f2a91bc",
// "placedAt": "2026-03-10T14:22:00.000Z",
// "total": 42.98
// }Come formatto una stringa JSON (non un oggetto) in JavaScript?
Prima analizza la stringa con JSON.parse(), poi riseriallizzala con JSON.stringify(). Le due chiamate possono essere concatenate in una singola riga per un debug rapido.
const raw = '{"endpoint":"/api/v2/users","timeout":30,"retry":true}'
const formatted = JSON.stringify(JSON.parse(raw), null, 2)
console.log(formatted)
// {
// "endpoint": "/api/v2/users",
// "timeout": 30,
// "retry": true
// }Posso usare JSON.stringify() nel browser?
Sì. JSON è un oggetto globale integrato in tutti i browser moderni dal IE8 — senza tag script né importazioni. Apri la console DevTools e chiama JSON.stringify() direttamente. Funziona in modo identico alla versione Node.js, con la stessa firma dei parametri e le stesse limitazioni riguardo a BigInt e riferimenti circolari.
// Funziona in Chrome, Firefox, Safari, Edge — senza importazioni
const payload = { userId: "usr_7b3c", action: "checkout", cart: ["SKU-001", "SKU-002"] }
copy(JSON.stringify(payload, null, 2)) // copy() è un helper di DevToolsJavaScript ti dà il pieno controllo — funzioni replacer, toJSON() personalizzato, elaborazione di file di grandi dimensioni in Node.js. Quando hai solo bisogno di ispezionare o condividere uno snippet formattato, il Formattatore JSON di ToolDeck è la strada più veloce: incolla il tuo JSON e ottieni un risultato formattato ed evidenziato senza alcuna configurazione dell'ambiente.
Strumenti correlati
Alex is a front-end and Node.js developer with extensive experience building web applications and developer tooling. He is passionate about web standards, browser APIs, and the JavaScript ecosystem. In his spare time he contributes to open-source projects and writes about modern JavaScript patterns, performance optimisation, and everything related to the web platform.
Marcus specialises in JavaScript performance, build tooling, and the inner workings of the V8 engine. He has spent years profiling and optimising React applications, working on bundler configurations, and squeezing every millisecond out of critical rendering paths. He writes about Core Web Vitals, JavaScript memory management, and the tools developers reach for when performance really matters.