Ipotizziamo di avere un oggetto complesso, che vogliamo convertire a stringa prima trasmetterlo in rete, o anche solo per mostrarlo sullo schermo.
Naturalmente, una stringa di questo tipo deve includere tutte le proprietà importanti.
Potremmo implementarla in questo modo:
let user = {
name: "John",
age: 30,
toString() {
return `{name: "${this.name}", age: ${this.age}}`;
}
};
alert(user); // {name: "John", age: 30}
…Ma nel processo di sviluppo, potrebbero essere aggiunte/eliminate/rinominate nuove proprietà. Aggiornare costantemente la funzione toString non è una buona soluzione. Potremmo provare a iterare sulle proprietà dell’oggetto, ma cosa succederebbe se l’oggetto contenesse oggetti annidati? Dovremmo implementare anche questa conversione. E se dovessimo inviare l’oggetto in rete, dovremmo anche fornire il codice per poterlo “leggere”.
Fortunatamente, non c’è bisogno di scrivere del codice per gestire questa situazione.
JSON.stringify
JSON (JavaScript Object Notation) è un formato per rappresentare valori e oggetti. Viene descritto nello standard RFC 4627. Inizialmente fu creato per lavorare con JavaScript, ma molti altri linguaggi possiedono delle librerie per la sua gestione. Quindi JSON risulta semplice da usare per lo scambio di dati quando il client utilizza JavaScript e il server codifica in Ruby/PHP/Java/Altro.
JavaScript fornisce i metodi:
JSON.stringifyper convertire oggetti in JSON.JSON.parseper convertire JSON in oggetto.
Ad esempio, abbiamo JSON.stringify per uno studente:
let student = {
name: 'John',
age: 30,
isAdmin: false,
courses: ['html', 'css', 'js'],
wife: null
};
let json = JSON.stringify(student);
alert(typeof json); //abbiamo una stringa!
alert(json);
/* JSON-encoded object:
{
"name": "John",
"age": 30,
"isAdmin": false,
"courses": ["html", "css", "js"],
"wife": null
}
*/
Il metodo JSON.stringify(student) prende l’oggetto e lo converte in stringa.
La stringa json risultante viene chiamata codifica in JSON o serializzata, stringhificata, o addirittura oggetto caramellizzato. Ora è pronto per essere inviato o memorizzato.
Da notare che un oggetto codificato in JSON possiede delle fondamentali differenze da un oggetto letterale:
- Le stringhe utilizzano doppie virgolette. In JSON non vengono utilizzare backtick o singole virgolette. Quindi
'John'diventa"John". - Anche i nomi delle proprietà dell’oggetto vengono racchiusi tra doppie virgolette. Quindi
age:30diventa"age":30.
JSON.stringify può anche essere applicato agli oggetti primitivi.
I tipi che supportano nativamente JSON sono:
- Objects
{ ... } - Arrays
[ ... ] - Primitives:
- strings,
- numbers,
- valori boolean
true/false, null.
Ad esempio:
// un numero in JSON è solo un numero
alert( JSON.stringify(1) ) // 1
// una stringa in JSON è ancora una stringa, ma con doppie virgolette
alert( JSON.stringify('test') ) // "test"
alert( JSON.stringify(true) ); // true
alert( JSON.stringify([1, 2, 3]) ); // [1,2,3]
JSON è un linguaggio specifico per i dati, quindi alcune proprietà specifiche di JavaScript vengono ignorate da JSON.stringify.
Tra cui:
- Funzioni (metodi).
- Proprietà di tipo symbol.
- Proprietà che contengono
undefined.
let user = {
sayHi() { // ignorato
alert("Hello");
},
[Symbol("id")]: 123, // ignorato
something: undefined // ignorato
};
alert( JSON.stringify(user) ); // {} (oggetto vuoto)
Solitamente questo è ciò che vogliamo. Se invece abbiamo intenzioni diverse, molto presto vedremo come controllare il processo.
Un’ottima cosa è che anche gli oggetti annidati vengono automaticamente convertiti.
Ad esempio:
let meetup = {
title: "Conference",
room: {
number: 23,
participants: ["john", "ann"]
}
};
alert( JSON.stringify(meetup) );
/* Tutta la struttura viene serializzata
{
"title":"Conference",
"room":{"number":23,"participants":["john","ann"]},
}
*/