JSON.stringify()

 

Il metodo JSON.stringify() converte un oggetto o un valore JavaScript in una stringa JSON, sostituendo facoltativamente i valori se viene specificata una funzione sostitutiva o facoltativamente includendo solo le propriet√† specificate se viene specificato un array replacer.

Sintassi

JSON.stringify(value[, replacer[, space]])

Parametri

value
Il valore da convertire in stringa JSON.
replacerOptional
Una funzione che altera il processo di conversione, o un array di String e Number che contiene le propriet√† dell'oggetto che devono essere incluse nella stringa JSON. Se il valore √® null o non √® specificato, tutte le propriet√† dell'oggetto sono incluse nel risultato.
spaceOptional
Un oggetto StringNumber che viene utilizzato per inserire uno spazio bianco nella stringa JSON di output a fini di leggibilit√†.Se questo √® un Number, indica il numero di caratteri dello spazio da usare come spazio bianco; questo numero √® limitato a 10 (se √® maggiore, il valore √® solo 10).Valori inferiori a 1 indicano che non deve essere usato alcuno spazio.

Se si tratta di una  String, la stringa (i primi 10 caratteri della stringa, se √® pi√Ļ lunga di quella) viene utilizzata come spazio bianco. Se questo parametro non viene fornito (o √® null), non viene utilizzato alcuno spazio bianco.

Valore di ritorno

Una stringa JSON che rappresenta il valore dato.

Eccezioni

Genera un'eccezione TypeError ("valore dell'oggetto ciclico") quando viene trovato un riferimento circolare.

Descrizione

JSON.stringify() converte un valore in notazione JSON che lo rappresenta:

  • Se il valore ha un metodo toJSON() √® responsabile definire quali dati verranno serializzati.
  • Gli oggetti Boolean, Number, e String vengono convertiti ai corrispondenti valori primitivi durante la stringificazione, in accordo con la semantica di conversione tradizionale.
  • Se si incontrano undefined, una Function, o un Symbol durante la conversione, viene omesso (quando viene trovato in un oggetto) o viene censurato null (quando viene trovato in un array). JSON.stringify() pu√≤ anche restituire undefined quando si passa in valori "puri" come JSON.stringify(function(){}) o JSON.stringify(undefined).
  • Tutte le propriet√† Symbol-keyed saranno completamente ignorate, anche quando si utilizza la funzione replacer.
  • Le istanze di Date implementano la funzione toJSON() restituendo una stringa (la stessa di date.toISOString()). Quindi, sono trattati come stringhe.
JSON.stringify({});                  // '{}'
JSON.stringify(true);                // 'true'
JSON.stringify('foo');               // '"foo"'
JSON.stringify([1, 'false', false]); // '[1,"false",false]'
JSON.stringify({ x: 5 });            // '{"x":5}'

JSON.stringify({ x: 5, y: 6 });
// '{"x":5,"y":6}' or '{"y":6,"x":5}'
JSON.stringify([new Number(1), new String('false'), new Boolean(false)]);
// '[1,"false",false]'

// Simboli:
JSON.stringify({ x: undefined, y: Object, z: Symbol('') });
// '{}'
JSON.stringify({ [Symbol('foo')]: 'foo' });
// '{}'
JSON.stringify({ [Symbol.for('foo')]: 'foo' }, [Symbol.for('foo')]);
// '{}'
JSON.stringify({ [Symbol.for('foo')]: 'foo' }, function(k, v) {
  if (typeof k === 'symbol') {
    return 'a symbol';
  }
});
// '{}'

// Proprietà non enumerabili:
JSON.stringify( Object.create(null, { x: { value: 'x', enumerable: false }, y: { value: 'y', enumerable: true } }) );
// '{"y":"y"}'

Il parametro replacer

Il parametro replacer pu√≤ essere una funzione o un array.

Come una funzione, prende due parametri: la chiave e il valore che si sta stringendo. L'oggetto in cui √® stata trovata la chiave viene fornito come il parametro this del replacer.

Inizialmente, la funzione replacer viene chiamata con una stringa vuota come chiave che rappresenta l'oggetto da stringificare. Viene quindi chiamato per ogni propriet√† sull'oggetto o sull'array da stringificare.

  • Se si restituisce un Number, la stringa corrispondente a quel numero viene utilizzata come valore per la propriet√† quando viene aggiunta alla stringa JSON.
  • Se si restituisce una String, tale stringa viene utilizzata come valore della propriet√† quando viene aggiunta alla stringa JSON.
  • Se si restituisce un Boolean, "true" o "false" viene utilizzato come valore della propriet√†, come appropriato, quando viene aggiunto alla stringa JSON.
  • Se torni nullnull verr√† aggiunto alla stringa JSON.
  • Se si restituisce un qualsiasi altro oggetto, l'oggetto viene ricorsivamente stringa nella stringa JSON, chiamando la funzione replacer su ogni propriet√†, a meno che l'oggetto non sia una funzione, nel qual caso non viene aggiunto nulla alla stringa JSON.
  • Se si restituisce undefined, la propriet√† non √® inclusa (cio√® filtrata) nella stringa JSON di output.
Nota: Non √® possibile utilizzare la replacerfunzione per rimuovere i valori da una matrice. Se si restituisce undefinedo una funzione, nullviene invece utilizzata.
Se desideri che il replacer distingua un oggetto iniziale da una chiave con una propriet√† stringa vuota (poich√© entrambi fornirebbero la stringa vuota come chiave e potenzialmente un oggetto come valore), sar√† necessario tenere traccia del conteggio dell'iterazione (se √® al di l√† della prima iterazione, √® una vera e propria chiave di stringa vuota).

Esempio di replacer, come funzione

function replacer(key, value) {
  // Filtraggio delle proprietà
  if (typeof value === 'string') {
    return undefined;
  }
  return value;
}

var foo = {foundation: 'Mozilla', model: 'box', week: 45, transport: 'car', month: 7};
JSON.stringify(foo, replacer);
// Risultato: '{"week":45,"month":7}'

Esempio di replacer, come array

Se replacer √® un array, i valori dell'array indicano i nomi delle propriet√† nell'oggetto che dovrebbero essere incluse nella stringa JSON risultante.

JSON.stringify(foo, ['week', 'month']);
// '{"week":45,"month":7}', mantiene solo le proprietà "week" e "month"

Il parametro space

L'argomento space pu√≤ essere usato per controllare la spaziatura nella stringa finale.

  • Se si tratta di un numero, i livelli successivi nella stringa verranno rientrati da questi caratteri di spazio (fino a 10).
  • Se √® una stringa, i livelli successivi saranno rientrati da questa stringa (o dai primi dieci caratteri di essa).
JSON.stringify({ a: 2 }, null, ' ');
// '{
//  "a": 2
// }'

L'utilizzo di un carattere di tabulazione simula l'aspetto standard di tipo "pretty-print":

JSON.stringify({ uno: 1, dos: 2 }, null, '\t');
// restituisce la stringa:
// '{
//     "uno": 1,
//     "dos": 2
// }'

Comportamento di toJSON()

Se un oggetto da stringificare ha una propriet√† denominata il toJSON cui valore √® una funzione, il metodo toJSON() personalizza il comportamento di stringificazione JSON: invece dell'oggetto serializzato, il valore restituito dal metodo toJSON() quando chiamato verr√† serializzato. JSON.stringify() chiama toJSON con un parametro:

  • se questo oggetto √® un valore di propriet√†, il nome della propriet√†
  • se √® in una matrice, l'indice nella matrice, come una stringa
  • una stringa vuota se √® JSON.stringify() stata richiamata direttamente su questo oggetto

Per esempio:

var obj = {
    data: 'data',

    toJSON(key){
        if(key)
            return `Ora sono un oggetto nidificato sotto chiave '${key}'`;

        else
            return this;
    }
};

JSON.stringify(obj);
// '{"data":"data"}'

JSON.stringify({ obj })
// '{"obj":"Ora sono un oggetto nidificato sotto chiave 'obj'"}'

JSON.stringify([ obj ])
// '["Ora sono un oggetto nidificato sotto chiave '0'"]'

Problema con JSON.stringify() durante la serializzazione di riferimenti circolari

Nota che poich√© il Formato JSON non supporta i riferimenti agli oggetti (sebbene esista una bozza IETF), TypeError verr√† generato un se si tenta di codificare un oggetto con riferimenti circolari.

const circularReference = {};
circularReference.myself = circularReference;

// La serializzazione dei riferimenti circolari genera "TypeError: valore dell'oggetto ciclico"
JSON.stringify(circularReference);

Per serializzare i riferimenti circolari √® possibile utilizzare una libreria che li supporta (ad es. cycle.js di Douglas Crockford) o implementare una soluzione autonomamente, che richieder√† la ricerca e la sostituzione (o la rimozione) dei riferimenti ciclici mediante valori serializzabili.

Problema con plain  JSON.stringify per l'uso come JavaScript

Storicamente, JSON non era un sottoinsieme completamente rigido di JavaScript. I punti del codice letterale U + 2028 LINE SEPARATOR e U + 2029 PARAGRAPH SEPARATOR potrebbero apparire letteralmente in stringhe letterali e nomi di propriet√† nel testo JSON. Ma non potevano apparire letteralmente in un contesto simile nel testo JavaScript - solo usando escape Unicode come \u2028\u2029.  Questo √® cambiato di recente: ora entrambi i punti di codice possono apparire letteralmente nelle stringhe in JSON e JavaScript entrambi.

Pertanto, se √® richiesta la compatibilit√† con i motori JavaScript precedenti, √® pericoloso sostituire direttamente la stringa restituita da JSON.stringify una stringa JavaScript da passare a eval new Function o come parte di un URL JSONP e pu√≤ essere utilizzata la seguente utility:

function jsFriendlyJSONStringify (s) {
    return JSON.stringify(s).
        replace(/\u2028/g, '\\u2028').
        replace(/\u2029/g, '\\u2029');
}

var s = {
    a: String.fromCharCode(0x2028),
    b: String.fromCharCode(0x2029)
};
try {
    eval('(' + JSON.stringify(s) + ')');
} catch (e) {
    console.log(e); // "SyntaxError: unterminated string literal"
}

// No need for a catch
eval('(' + jsFriendlyJSONStringify(s) + ')');

// console.log in Firefox scolla l'Unicode se
//   connesso alla console, quindi usiamo alert
alert(jsFriendlyJSONStringify(s)); // {"a":"\u2028","b":"\u2029"}

Note: Non √® garantito che le propriet√† degli oggetti non array vengano sottoposte a stringa in qualsiasi ordine particolare. Non fare affidamento sull'ordinamento di propriet√† all'interno dello stesso oggetto all'interno della stringa.

var a = JSON.stringify({ foo: "bar", baz: "quux" })
//'{"foo":"bar","baz":"quux"}'
var b = JSON.stringify({ baz: "quux", foo: "bar" })
//'{"baz":"quux","foo":"bar"}'
console.log(a !== b) // true

// alcune funzioni di memoizzazione usano JSON.stringify per serializzare gli argomenti,
// mancando la cache quando si incontra lo stesso oggetto come sopra

Esempio di utilizzo JSON.stringify() con localStorage

Nel caso in cui desideri archiviare un oggetto creato dall'utente e consentirne il ripristino anche dopo la chiusura del browser, nell'esempio seguente √® disponibile un modello per l'applicabilit√† di JSON.stringify():

// Creare un esempio di JSON
var session = {
  'screens': [],
  'state': true
};
session.screens.push({ 'name': 'screenA', 'width': 450, 'height': 250 });
session.screens.push({ 'name': 'screenB', 'width': 650, 'height': 350 });
session.screens.push({ 'name': 'screenC', 'width': 750, 'height': 120 });
session.screens.push({ 'name': 'screenD', 'width': 250, 'height': 60 });
session.screens.push({ 'name': 'screenE', 'width': 390, 'height': 120 });
session.screens.push({ 'name': 'screenF', 'width': 1240, 'height': 650 });

// Conversione della stringa JSON con JSON.stringify()
// quindi salva con localStorage nel nome della sessione
localStorage.setItem('session', JSON.stringify(session));

// Esempio di come trasformare la stringa generata tramite
// JSON.stringify() e salvare nuovamente in localStorage nell'oggetto JSON
var restoredSession = JSON.parse(localStorage.getItem('session'));

// Ora la variabile restoreSession contiene l'oggetto che è stato salvato
// in localStorage
console.log(restoredSession);

Well-formed JSON.stringify()

Engines implementing the well-formed JSON.stringify specification will stringify lone surrogates -- any code point from U+D800 to U+DFFF -- using Unicode escape sequences rather than literally.  Before this change JSON.stringify would output lone surrogates if the input contained any lone surrogates; such strings could not be encoded in valid UTF-8 or UTF-16:

JSON.stringify("\uD800"); // '"ÔŅĹ"'

Ma con questo cambiamento JSON.stringify rappresentano surrogati solitari usando sequenze di escape JSON che possono essere codificate in UTF-8 o UTF-16 validi:

JSON.stringify("\uD800"); // '"\\ud800"'

Questo cambiamento dovrebbe essere retrocompatibile fin tanto che si passa il risultato di JSON.stringify API come JSON.parse quella che accetter√† qualsiasi testo JSON valido, in quanto tratter√† le escape Unicode dei surrogati soli come identici ai surrogati solitari stessi.  Solo se stai interpretando direttamente il risultato di JSON.stringify hai bisogno di gestire attentamente JSON.stringify le due possibili codifiche di questi punti di codice.

Specifiche

Compatiblità con i browser

BCD tables only load in the browser

Vedi anche

  • JSON.parse()
  • cycle.js ‚Äď Presenta due funzioni: JSON.decycle e JSON.retrocycle. Esse consentono la codifica e la decodifica di strutture cicliche e DAG in un formato JSON esteso e retrocompatibile.