← Torna al Blog

JavaScript e JSON: Guida completa a JSON.parse() e JSON.stringify()

Guida completa su JSON in JavaScript: parsing, serializzazione, gestione errori, localStorage, fetch API e best practices. Include esempi pratici e troubleshooting.

Big JSON Team14 min di letturaprogramming
B

Big JSON Team

Technical Writer

Expert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.

14 min di lettura

# JavaScript e JSON: Guida completa a JSON.parse() e JSON.stringify()

JavaScript e JSON sono inseparabili nello sviluppo web moderno. Questa guida ti insegnerà tutto ciò che devi sapere per lavorare con JSON in JavaScript in modo professionale.

Perché JSON e JavaScript sono perfetti insieme

JSON (JavaScript Object Notation) è nato da JavaScript e la sintassi è quasi identica agli oggetti JavaScript literal, rendendoli naturalmente compatibili.

// Oggetto JavaScript

const obj = {

nome: "Marco",

età: 30

};

// JSON (stringa)

const json = '{"nome":"Marco","età":30}';

JSON.parse() - Da stringa a oggetto

Sintassi base

const jsonString = '{"nome":"Marco","città":"Milano"}';

const obj = JSON.parse(jsonString);

console.log(obj.nome); // "Marco"

console.log(obj.città); // "Milano"

Parsing di tipi diversi

// Oggetto

const obj = JSON.parse('{"chiave":"valore"}');

console.log(typeof obj); // "object"

// Array

const arr = JSON.parse('["mela","banana","arancia"]');

console.log(Array.isArray(arr)); // true

// Numero

const num = JSON.parse('42');

console.log(typeof num); // "number"

// String

const str = JSON.parse('"ciao"');

console.log(typeof str); // "string"

// Boolean

const bool = JSON.parse('true');

console.log(typeof bool); // "boolean"

// Null

const n = JSON.parse('null');

console.log(n === null); // true

Gestione errori

function safeParse(jsonString) {

try {

return JSON.parse(jsonString);

} catch (error) {

console.error('Errore parsing JSON:', error.message);

return null;

}

}

// JSON valido

const valido = safeParse('{"nome":"Marco"}');

console.log(valido); // { nome: "Marco" }

// JSON non valido

const invalido = safeParse('{nome:"Marco"}'); // Mancano virgolette

console.log(invalido); // null

// Console: Errore parsing JSON: Unexpected token n in JSON at position 1

Reviver function

La funzione reviver permette di trasformare i valori durante il parsing:

const jsonString = '{"nome":"Marco","data":"2026-01-26T10:30:00Z","prezzo":"99.99"}';

const obj = JSON.parse(jsonString, (key, value) => {

// Converti date ISO in oggetti Date

if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}T/.test(value)) {

return new Date(value);

}

// Converti stringhe numeriche in numeri

if (key === 'prezzo' && typeof value === 'string') {

return parseFloat(value);

}

return value;

});

console.log(obj.data instanceof Date); // true

console.log(typeof obj.prezzo); // "number"

console.log(obj.prezzo); // 99.99

JSON.stringify() - Da oggetto a stringa

Sintassi base

const utente = {

nome: "Marco",

cognome: "Rossi",

età: 30,

città: "Milano"

};

const jsonString = JSON.stringify(utente);

console.log(jsonString);

// {"nome":"Marco","cognome":"Rossi","età":30,"città":"Milano"}

Formattazione con indentazione

const utente = {

nome: "Marco",

contatti: {

email: "marco@example.com",

telefono: "+39 02 1234 5678"

}

};

// Con 2 spazi di indentazione

const formatted = JSON.stringify(utente, null, 2);

console.log(formatted);

/

{

"nome": "Marco",

"contatti": {

"email": "marco@example.com",

"telefono": "+39 02 1234 5678"

}

}

/

// Con 4 spazi

const formatted4 = JSON.stringify(utente, null, 4);

// Con tab

const formattedTab = JSON.stringify(utente, null, '\t');

Replacer function

Il replacer filtra e trasforma i valori durante la serializzazione:

const utente = {

nome: "Marco",

cognome: "Rossi",

password: "secret123",

email: "marco@example.com",

età: 30,

saldo: 1000.50

};

// Filtra password

const json = JSON.stringify(utente, (key, value) => {

// Escludi password

if (key === 'password') {

return undefined;

}

// Arrotonda numeri

if (typeof value === 'number') {

return Math.round(value);

}

return value;

}, 2);

console.log(json);

/

{

"nome": "Marco",

"cognome": "Rossi",

"email": "marco@example.com",

"età": 30,

"saldo": 1001

}

/

Replacer array

const utente = {

nome: "Marco",

cognome: "Rossi",

password: "secret",

email: "marco@example.com",

telefono: "+39 123456789"

};

// Include solo nome ed email

const json = JSON.stringify(utente, ['nome', 'email'], 2);

console.log(json);

/

{

"nome": "Marco",

"email": "marco@example.com"

}

/

toJSON method

Oggetti con metodo toJSON() controllano la propria serializzazione:

class Utente {

constructor(nome, cognome, password) {

this.nome = nome;

this.cognome = cognome;

this.password = password;

}

toJSON() {

// Personalizza la serializzazione

return {

nomeCompleto: ${this.nome} ${this.cognome},

// password esclusa automaticamente

};

}

}

const utente = new Utente("Marco", "Rossi", "secret123");

const json = JSON.stringify(utente, null, 2);

console.log(json);

/

{

"nomeCompleto": "Marco Rossi"

}

/

Tipi di dati supportati

Valori supportati

const supportati = {

string: "testo",

number: 42,

boolean: true,

null: null,

object: { chiave: "valore" },

array: [1, 2, 3]

};

JSON.stringify(supportati, null, 2);

// Tutti convertiti correttamente

Valori NON supportati

const nonSupportati = {

funzione: function() { return "ciao"; },

undefined: undefined,

symbol: Symbol("test"),

data: new Date(),

regex: /test/g,

infinito: Infinity,

nan: NaN

};

console.log(JSON.stringify(nonSupportati, null, 2));

/

{

"data": "2026-01-26T10:30:00.000Z", // Convertita in ISO string

"infinito": null, // Diventa null

"nan": null // Diventa null

}

/

// funzione, undefined e symbol sono omessi!

Gestione Date

const obj = {

nome: "Marco",

creato: new Date('2026-01-26T10:30:00Z')

};

// Date diventa ISO string

const json = JSON.stringify(obj);

console.log(json);

// {"nome":"Marco","creato":"2026-01-26T10:30:00.000Z"}

// Riparsing con conversione

const parsed = JSON.parse(json, (key, value) => {

if (key === 'creato') {

return new Date(value);

}

return value;

});

console.log(parsed.creato instanceof Date); // true

Uso con fetch API

GET Request

// Fetch automaticamente parsa JSON

fetch('https://api.example.com/users/123')

.then(response => response.json()) // Parse automatico

.then(utente => {

console.log(utente.nome);

console.log(utente.email);

})

.catch(error => console.error('Errore:', error));

POST Request

const nuovoUtente = {

nome: "Marco",

email: "marco@example.com",

ruolo: "admin"

};

fetch('https://api.example.com/users', {

method: 'POST',

headers: {

'Content-Type': 'application/json',

},

body: JSON.stringify(nuovoUtente) // Serializza oggetto

})

.then(response => response.json())

.then(data => {

console.log('Utente creato:', data);

})

.catch(error => console.error('Errore:', error));

Async/Await

async function getUtente(id) {

try {

const response = await fetch(https://api.example.com/users/${id});

if (!response.ok) {

throw new Error(HTTP error! status: ${response.status});

}

const utente = await response.json();

return utente;

} catch (error) {

console.error('Errore fetch:', error);

return null;

}

}

// Uso

const utente = await getUtente(123);

if (utente) {

console.log(utente.nome);

}

Gestione errori completa

async function apiCall(url, options = {}) {

try {

const response = await fetch(url, options);

// Verifica status HTTP

if (!response.ok) {

throw new Error(HTTP ${response.status}: ${response.statusText});

}

// Verifica Content-Type

const contentType = response.headers.get('content-type');

if (!contentType || !contentType.includes('application/json')) {

throw new Error('Response non è JSON');

}

// Parse JSON

const data = await response.json();

return { success: true, data };

} catch (error) {

console.error('Errore API:', error);

return { success: false, error: error.message };

}

}

// Uso

const result = await apiCall('https://api.example.com/data');

if (result.success) {

console.log('Dati:', result.data);

} else {

console.error('Errore:', result.error);

}

localStorage e sessionStorage

Salvataggio

const preferenze = {

tema: "scuro",

lingua: "it",

notifiche: true,

layout: {

sidebar: "sinistra",

densità: "compatta"

}

};

// Salva in localStorage

localStorage.setItem('preferenze', JSON.stringify(preferenze));

// Salva in sessionStorage

sessionStorage.setItem('tempData', JSON.stringify({ id: 123 }));

Recupero

// Recupera da localStorage

const preferenzeString = localStorage.getItem('preferenze');

if (preferenzeString) {

try {

const preferenze = JSON.parse(preferenzeString);

console.log(preferenze.tema); // "scuro"

console.log(preferenze.lingua); // "it"

} catch (error) {

console.error('Errore parsing preferenze:', error);

}

}

Utility functions

// Utility per localStorage con JSON

const storage = {

get(key, defaultValue = null) {

try {

const item = localStorage.getItem(key);

return item ? JSON.parse(item) : defaultValue;

} catch (error) {

console.error(Errore lettura ${key}:, error);

return defaultValue;

}

},

set(key, value) {

try {

localStorage.setItem(key, JSON.stringify(value));

return true;

} catch (error) {

console.error(Errore scrittura ${key}:, error);

return false;

}

},

remove(key) {

localStorage.removeItem(key);

},

clear() {

localStorage.clear();

}

};

// Uso

storage.set('utente', { nome: "Marco", id: 123 });

const utente = storage.get('utente');

console.log(utente.nome); // "Marco"

Deep cloning con JSON

const originale = {

nome: "Marco",

contatti: {

email: "marco@example.com",

telefono: "+39 123456"

},

hobby: ["programmazione", "viaggi"]

};

// Deep clone

const clone = JSON.parse(JSON.stringify(originale));

// Modifica clone

clone.nome = "Laura";

clone.contatti.email = "laura@example.com";

clone.hobby.push("fotografia");

// Originale non modificato

console.log(originale.nome); // "Marco"

console.log(originale.contatti.email); // "marco@example.com"

console.log(originale.hobby.length); // 2

console.log(clone.nome); // "Laura"

console.log(clone.hobby.length); // 3

⚠️ Limitazioni del cloning con JSON:
const obj = {

data: new Date(),

funzione: () => "test",

undefined: undefined,

regex: /test/g,

map: new Map([['a', 1]]),

set: new Set([1, 2, 3])

};

const clone = JSON.parse(JSON.stringify(obj));

console.log(clone.data instanceof Date); // false (è stringa)

console.log(clone.funzione); // undefined (persa)

console.log(clone.regex); // {} (diventa oggetto vuoto)

console.log(clone.map); // {} (diventa oggetto vuoto)

// Per questi casi usa structuredClone() (moderno)

const betterClone = structuredClone(obj);

Pretty printing

function prettyPrint(obj) {

console.log(JSON.stringify(obj, null, 2));

}

const dati = {

utente: {

nome: "Marco",

età: 30

},

prodotti: [

{ id: 1, nome: "Laptop" },

{ id: 2, nome: "Mouse" }

]

};

prettyPrint(dati);

/

{

"utente": {

"nome": "Marco",

"età": 30

},

"prodotti": [

{

"id": 1,

"nome": "Laptop"

},

{

"id": 2,

"nome": "Mouse"

}

]

}

/

Validazione JSON

function isValidJSON(str) {

try {

JSON.parse(str);

return true;

} catch (e) {

return false;

}

}

console.log(isValidJSON('{"nome":"Marco"}')); // true

console.log(isValidJSON('{nome:"Marco"}')); // false

console.log(isValidJSON('not json')); // false

Validazione con dettagli errore

function validateJSON(str) {

try {

const obj = JSON.parse(str);

return {

valid: true,

data: obj,

error: null

};

} catch (error) {

return {

valid: false,

data: null,

error: {

message: error.message,

position: error.message.match(/position (\d+)/)?.[1]

}

};

}

}

const result = validateJSON('{invalid json}');

console.log(result);

/

{

valid: false,

data: null,

error: {

message: "Unexpected token i in JSON at position 1",

position: "1"

}

}

/

Performance e ottimizzazione

Benchmark: parse vs eval

const jsonString = '{"nome":"Marco","età":30}';

// ✅ JSON.parse - Sicuro e veloce

console.time('JSON.parse');

for (let i = 0; i < 100000; i++) {

JSON.parse(jsonString);

}

console.timeEnd('JSON.parse');

// ❌ eval - PERICOLOSO! Non usare!

console.time('eval');

for (let i = 0; i < 100000; i++) {

eval('(' + jsonString + ')');

}

console.timeEnd('eval');

// JSON.parse è più veloce E sicuro

Minificazione

const obj = {

nome: "Marco",

età: 30,

città: "Milano"

};

// Minificato (nessuno spazio)

const minified = JSON.stringify(obj);

console.log(minified);

// {"nome":"Marco","età":30,"città":"Milano"}

// Dimensione ridotta

console.log('Formattato:', JSON.stringify(obj, null, 2).length); // 52

console.log('Minificato:', minified.length); // 40

// Risparmio: ~23%

Best practices

1. Usa sempre try-catch con JSON.parse

// ✅ Corretto

try {

const data = JSON.parse(jsonString);

} catch (error) {

console.error('JSON non valido:', error);

}

// ❌ Da evitare

const data = JSON.parse(jsonString); // Può crashare l'app

2. Valida Content-Type nelle fetch

// ✅ Corretto

const response = await fetch(url);

const contentType = response.headers.get('content-type');

if (contentType && contentType.includes('application/json')) {

const data = await response.json();

}

// ❌ Assume sempre JSON

const data = await response.json(); // Può fallire

3. Non usare eval() per JSON

// ✅ Corretto e sicuro

const obj = JSON.parse('{"nome":"Marco"}');

// ❌ PERICOLOSO! Vulnerabile a code injection

const obj = eval('(' + '{"nome":"Marco"}' + ')');

4. Gestisci circular references

const obj = { nome: "Marco" };

obj.self = obj; // Circular reference

// ❌ Questo fallisce

try {

JSON.stringify(obj);

} catch (error) {

console.error(error); // TypeError: Converting circular structure to JSON

}

// ✅ Usa WeakSet per tracciare oggetti visitati

function stringifyWithoutCircular(obj) {

const seen = new WeakSet();

return JSON.stringify(obj, (key, value) => {

if (typeof value === "object" && value !== null) {

if (seen.has(value)) {

return "[Circular]";

}

seen.add(value);

}

return value;

});

}

console.log(stringifyWithoutCircular(obj));

5. Sanitizza dati sensibili

const utente = {

nome: "Marco",

email: "marco@example.com",

password: "secret123",

token: "abc123xyz"

};

// Rimuovi dati sensibili prima di stringify

const safe = JSON.stringify(utente, (key, value) => {

if (['password', 'token'].includes(key)) {

return undefined;

}

return value;

}, 2);

Conclusione

JavaScript e JSON formano una coppia potente per lo sviluppo web:

Metodi essenziali:
  • JSON.parse() - Stringa → Oggetto
  • JSON.stringify() - Oggetto → Stringa

Usi comuni:
  • API REST con fetch
  • localStorage/sessionStorage
  • Deep cloning
  • Configurazione

Best practices:
  • Gestisci sempre gli errori
  • Valida Content-Type
  • Non usare eval()
  • Formatta per leggibilità
  • Sanitizza dati sensibili

Con queste conoscenze, sei pronto a lavorare professionalmente con JSON in JavaScript!

Share:

Articoli Correlati

Read in English