Recherche…
Introduction
JSON (JavaScript Object Notation) est un format d'échange de données léger. Il est facile pour les humains de lire et d’écrire, et facile à analyser et à générer pour les machines. Il est important de réaliser qu'en JavaScript, JSON est une chaîne et non un objet.
Un aperçu de base peut être trouvé sur le site Web json.org qui contient également des liens vers des implémentations de la norme dans de nombreux langages de programmation différents.
Syntaxe
- JSON.parse (entrée [, reviver])
- JSON.stringify (valeur [, remplaçant [, espace]])
Paramètres
Paramètre | Détails |
---|---|
JSON.parse | Analyser une chaîne JSON |
input(string) | Chaîne JSON à analyser. |
reviver(function) | Prescrit une transformation pour la chaîne JSON en entrée. |
JSON.stringify | Sérialiser une valeur sérialisable |
value(string) | Valeur à sérialiser selon la spécification JSON. |
replacer(function ou String[] ou Number[]) | Inclut sélectivement certaines propriétés de l'objet de value . |
space(String ou Number ) | Si un number est fourni, alors space nombre d'espace des espaces blancs sera inséré de lisibilité. Si une string est fournie, la chaîne (10 premiers caractères) sera utilisée comme espaces blancs. |
Remarques
Les méthodes utilitaires JSON ont été normalisées pour la première fois dans ECMAScript 5.1 §15.12 .
Le format a été formellement défini dans Le type de support application / json pour JSON (RFC 4627 juillet 2006), mis à jour ultérieurement dans le format JSON Data Interchange Format (RFC 7158 mars 2013, ECMA-404 octobre 2013 et RFC 7159 mars 2014).
Pour rendre ces méthodes disponibles dans les anciens navigateurs tels qu'Internet Explorer 8, utilisez json2.js de Douglas Crockford.
Analyse d'une chaîne JSON simple
La méthode JSON.parse()
analyse une chaîne en tant que JSON et renvoie une primitive, un tableau ou un objet JavaScript:
const array = JSON.parse('[1, 2, "c", "d", {"e": false}]');
console.log(array); // logs: [1, 2, "c", "d", {e: false}]
Sérialiser une valeur
Une valeur JavaScript peut être convertie en chaîne JSON à l'aide de la fonction JSON.stringify
.
JSON.stringify(value[, replacer[, space]])
-
value
Valeur à convertir en chaîne JSON.
/* Boolean */ JSON.stringify(true) // 'true'
/* Number */ JSON.stringify(12) // '12'
/* String */ JSON.stringify('foo') // '"foo"'
/* Object */ JSON.stringify({}) // '{}'
JSON.stringify({foo: 'baz'}) // '{"foo": "baz"}'
/* Array */ JSON.stringify([1, true, 'foo']) // '[1, true, "foo"]'
/* Date */ JSON.stringify(new Date()) // '"2016-08-06T17:25:23.588Z"'
/* Symbol */ JSON.stringify({x:Symbol()}) // '{}'
-
replacer
Fonction qui modifie le comportement du processus de stringification ou un tableau d'objets String et Number servant de liste blanche pour filtrer les propriétés de l'objet value à inclure dans la chaîne JSON. Si cette valeur est null ou n'est pas fournie, toutes les propriétés de l'objet sont incluses dans la chaîne JSON résultante.
// replacer as a function
function replacer (key, value) {
// Filtering out properties
if (typeof value === "string") {
return
}
return value
}
var foo = { foundation: "Mozilla", model: "box", week: 45, transport: "car", month: 7 }
JSON.stringify(foo, replacer)
// -> '{"week": 45, "month": 7}'
// replacer as an array
JSON.stringify(foo, ['foundation', 'week', 'month'])
// -> '{"foundation": "Mozilla", "week": 45, "month": 7}'
// only the `foundation`, `week`, and `month` properties are kept
-
space
Pour des raisons de lisibilité, le nombre d'espaces utilisés pour l'indentation peut être spécifié comme troisième paramètre.
JSON.stringify({x: 1, y: 1}, null, 2) // 2 space characters will be used for indentation
/* output:
{
'x': 1,
'y': 1
}
*/
Une valeur de chaîne peut également être utilisée pour l'indentation. Par exemple, si vous transmettez '\t'
le caractère de tabulation sera utilisé pour l'indentation.
JSON.stringify({x: 1, y: 1}, null, '\t')
/* output:
{
'x': 1,
'y': 1
}
*/
Sérialisation avec une fonction de remplacement
Une fonction de replacer
peut être utilisée pour filtrer ou transformer les valeurs sérialisées.
const userRecords = [
{name: "Joe", points: 14.9, level: 31.5},
{name: "Jane", points: 35.5, level: 74.4},
{name: "Jacob", points: 18.5, level: 41.2},
{name: "Jessie", points: 15.1, level: 28.1},
];
// Remove names and round numbers to integers to anonymize records before sharing
const anonymousReport = JSON.stringify(userRecords, (key, value) =>
key === 'name'
? undefined
: (typeof value === 'number' ? Math.floor(value) : value)
);
Cela produit la chaîne suivante:
'[{"points":14,"level":31},{"points":35,"level":74},{"points":18,"level":41},{"points":15,"level":28}]'
Analyse avec une fonction de réanimation
Une fonction de réanimation peut être utilisée pour filtrer ou transformer la valeur analysée.
var jsonString = '[{"name":"John","score":51},{"name":"Jack","score":17}]';
var data = JSON.parse(jsonString, function reviver(key, value) {
return key === 'name' ? value.toUpperCase() : value;
});
const jsonString = '[{"name":"John","score":51},{"name":"Jack","score":17}]';
const data = JSON.parse(jsonString, (key, value) =>
key === 'name' ? value.toUpperCase() : value
);
Cela produit le résultat suivant:
[
{
'name': 'JOHN',
'score': 51
},
{
'name': 'JACK',
'score': 17
}
]
Ceci est particulièrement utile lorsque des données doivent être envoyées en série / encodées lorsqu’elles sont transmises avec JSON, mais on veut y accéder en les désérialisant / décodé. Dans l'exemple suivant, une date a été encodée dans sa représentation ISO 8601. Nous utilisons la fonction reviver pour analyser ceci dans une Date
JavaScript.
var jsonString = '{"date":"2016-01-04T23:00:00.000Z"}';
var data = JSON.parse(jsonString, function (key, value) {
return (key === 'date') ? new Date(value) : value;
});
const jsonString = '{"date":"2016-01-04T23:00:00.000Z"}';
const data = JSON.parse(jsonString, (key, value) =>
key === 'date' ? new Date(value) : value
);
Il est important de vous assurer que la fonction reviver renvoie une valeur utile à la fin de chaque itération. Si la fonction reviver renvoie undefined
, aucune valeur ou l'exécution ne tombe à la fin de la fonction, la propriété est supprimée de l'objet. Sinon, la propriété est redéfinie pour être la valeur de retour.
Sérialisation et restauration d'instances de classe
Vous pouvez utiliser une méthode toJSON
personnalisée et une fonction toJSON
pour transmettre des instances de votre propre classe dans JSON. Si un objet a une méthode toJSON
, son résultat sera sérialisé au lieu de l'objet lui-même.
function Car(color, speed) {
this.color = color;
this.speed = speed;
}
Car.prototype.toJSON = function() {
return {
$type: 'com.example.Car',
color: this.color,
speed: this.speed
};
};
Car.fromJSON = function(data) {
return new Car(data.color, data.speed);
};
class Car {
constructor(color, speed) {
this.color = color;
this.speed = speed;
this.id_ = Math.random();
}
toJSON() {
return {
$type: 'com.example.Car',
color: this.color,
speed: this.speed
};
}
static fromJSON(data) {
return new Car(data.color, data.speed);
}
}
var userJson = JSON.stringify({
name: "John",
car: new Car('red', 'fast')
});
Cela produit une chaîne avec le contenu suivant:
{"name":"John","car":{"$type":"com.example.Car","color":"red","speed":"fast"}}
var userObject = JSON.parse(userJson, function reviver(key, value) {
return (value && value.$type === 'com.example.Car') ? Car.fromJSON(value) : value;
});
Cela produit l'objet suivant:
{
name: "John",
car: Car {
color: "red",
speed: "fast",
id_: 0.19349242527065402
}
}
JSON versus littéraux JavaScript
JSON signifie "JavaScript Object Notation", mais pas JavaScript. Pensez-y comme un format de sérialisation de données qui se trouve être directement utilisable comme littéral JavaScript. Cependant, il n'est pas conseillé d'exécuter directement (c.-à-d. eval()
) JSON extrait d'une source externe. Fonctionnellement, JSON n'est pas très différent de XML ou YAML - une certaine confusion peut être évitée si JSON est simplement imaginé comme un format de sérialisation qui ressemble beaucoup à JavaScript.
Même si le nom n'implique que des objets, et même si la majorité des cas d'utilisation via une sorte d'API sont toujours des objets et des tableaux, JSON ne concerne pas uniquement les objets ou les tableaux. Les types primitifs suivants sont pris en charge:
- Chaîne (par exemple
"Hello World!"
) - Nombre (par exemple
42
) - Booléen (par exemple
true
) - La valeur
null
undefined
n'est pas pris en charge dans le sens où une propriété non définie sera omise de JSON lors de la sérialisation. Par conséquent, il n'y a aucun moyen de désérialiser JSON et de vous retrouver avec une propriété dont la valeur n'est undefined
.
La chaîne "42"
est valide JSON. JSON ne doit pas toujours avoir une enveloppe externe de "{...}"
ou "[...]"
.
Bien que nome JSON soit également valide en JavaScript et que JavaScript soit également valide, il existe quelques différences subtiles entre les deux langages et aucun des deux ne constitue un sous-ensemble de l'autre.
Prenez la chaîne JSON suivante comme exemple:
{"color": "blue"}
Cela peut être directement inséré dans JavaScript. Il sera syntaxiquement valide et donnera la valeur correcte:
const skin = {"color": "blue"};
Cependant, nous savons que "color" est un nom d'identifiant valide et que les guillemets autour du nom de la propriété peuvent être omis:
const skin = {color: "blue"};
Nous savons également que nous pouvons utiliser des guillemets simples au lieu de guillemets doubles:
const skin = {'color': 'blue'};
Mais, si nous prenions ces deux littéraux et les traitions comme JSON, aucun JSON ne serait syntaxiquement valide :
{color: "blue"}
{'color': 'blue'}
JSON exige strictement que tous les noms de propriété soient entre guillemets et que les valeurs de chaîne soient également entre guillemets.
Il est courant que les nouveaux venus JSON tentent d'utiliser des extraits de code avec des littéraux JavaScript en tant que JSON et qu'ils se penchent sur les erreurs de syntaxe qu'ils reçoivent du parseur JSON.
Plus de confusion commence à apparaître quand une terminologie incorrecte est appliquée dans le code ou dans la conversation.
Un anti-pattern commun consiste à nommer des variables qui contiennent des valeurs non-JSON comme "json":
fetch(url).then(function (response) {
const json = JSON.parse(response.data); // Confusion ensues!
// We're done with the notion of "JSON" at this point,
// but the concept stuck with the variable name.
});
Dans l'exemple ci-dessus, response.data
est une chaîne JSON renvoyée par certaines API. JSON s'arrête au domaine de réponse HTTP. La variable avec le terme incorrect "json" ne contient qu'une valeur JavaScript (peut être un objet, un tableau ou même un simple numéro!)
Une façon moins confuse d'écrire ce qui précède est la suivante:
fetch(url).then(function (response) {
const value = JSON.parse(response.data);
// We're done with the notion of "JSON" at this point.
// You don't talk about JSON after parsing JSON.
});
Les développeurs ont également tendance à lancer l'expression "objet JSON". Cela conduit également à la confusion. Parce que, comme mentionné ci-dessus, une chaîne JSON ne doit pas contenir un objet en tant que valeur. "Chaîne JSON" est un meilleur terme. Tout comme "Chaîne XML" ou "Chaîne YAML". Vous obtenez une chaîne, vous l’analyse et vous obtenez une valeur.
Valeurs d'objets cycliques
Tous les objets ne peuvent pas être convertis en chaîne JSON. Lorsqu'un objet a des auto-références cycliques, la conversion échouera.
C'est généralement le cas pour les structures de données hiérarchiques où parent et enfant se réfèrent l'un à l'autre:
const world = {
name: 'World',
regions: []
};
world.regions.push({
name: 'North America',
parent: 'America'
});
console.log(JSON.stringify(world));
// {"name":"World","regions":[{"name":"North America","parent":"America"}]}
world.regions.push({
name: 'Asia',
parent: world
});
console.log(JSON.stringify(world));
// Uncaught TypeError: Converting circular structure to JSON
Dès que le processus détecte un cycle, l'exception est déclenchée. S'il n'y avait pas de détection de cycle, la chaîne serait infiniment longue.