← Tous les articles

Comment sérialiser du JSON avec JSON.stringify

JSON.stringify convertit une valeur en chaîne JSON. Apprenez les arguments space et replacer, le hook toJSON et les valeurs qu'il abandonne silencieusement ou sur lesquelles il lève.

JSON.stringify() convertit une valeur JavaScript en chaîne JSON —— pour l’envoyer dans un corps de requête, l’enregistrer dans un fichier ou la stocker dans localStorage. Ça paraît simple, mais ses trois arguments, sa gestion des valeurs spéciales et le hook toJSON font régulièrement trébucher les devs. Ce guide couvre tout ce que fait JSON.stringify(), les équivalents dans d’autres langages, et les pièges à éviter.

Ce que fait JSON.stringify

Il parcourt une valeur de façon récursive et produit une chaîne JSON conforme à la spec. La sortie par défaut est compacte, sans blanc superflu :

const user = { name: "Ada", age: 36, active: true };

JSON.stringify(user);
// '{"name":"Ada","age":36,"active":true}'

Comme il émet toujours du JSON valide, vous ne devriez jamais construire des chaînes JSON à la main avec de la concaténation ou des template literals —— c’est la cause numéro 1 des erreurs [object Object] et des erreurs de virgules finales.

Les trois arguments

JSON.stringify(value, replacer, space) prend une valeur plus deux arguments optionnels que la plupart des devs n’utilisent jamais —— mais qui sont puissants.

space —— pretty-print

Le troisième argument contrôle l’indentation. Passez un nombre pour autant d’espaces, ou une chaîne comme '\t' pour des tabulations :

JSON.stringify(user, null, 2);
// {
//   "name": "Ada",
//   "age": 36,
//   "active": true
// }

C’est exactement comme ça qu’on pretty-print du JSON en code —— voir Comment formater du JSON. Omettez l’argument (ou passez 0) pour minifier ; voir Comment minifier du JSON.

replacer —— filtrer et transformer

Le deuxième argument peut être un tableau de clés à inclure, ou une fonction qui transforme chaque valeur :

// Liste blanche : seules ces clés survivent
JSON.stringify(user, ['name', 'active']);
// '{"name":"Ada","active":true}'

// Fonction : masquer un champ, supprimer un autre
JSON.stringify(
  { name: "Ada", password: "secret", token: "abc" },
  (key, value) => {
    if (key === 'password') return '[REDACTED]';
    if (key === 'token') return undefined; // retourner undefined omet la clé
    return value;
  },
);
// '{"name":"Ada","password":"[REDACTED]"}'

Le hook toJSON

Si une valeur a une méthode toJSON(), JSON.stringify() l’appelle et sérialise la valeur de retour à la place. C’est ainsi que les objets Date deviennent automatiquement des chaînes ISO :

JSON.stringify({ when: new Date('2026-05-24T00:00:00Z') });
// '{"when":"2026-05-24T00:00:00.000Z"}'  ← Date.prototype.toJSON exécuté

// Définir votre propre toJSON pour une sérialisation custom
class Money {
  constructor(cents) { this.cents = cents; }
  toJSON() { return (this.cents / 100).toFixed(2); }
}
JSON.stringify({ price: new Money(1999) });
// '{"price":"19.99"}'

Ce qui est supprimé ou converti

JSON n’a que six types, donc les valeurs JavaScript sans équivalent JSON sont silencieusement supprimées ou converties —— source fréquente de bugs d’aller-retour :

Valeur JavaScriptRésultat de JSON.stringify
undefined (dans un objet)clé omise
undefined (dans un tableau)null
fonctionomise (objet) / null (tableau)
Symbolomis
NaN, Infinitynull
Datechaîne ISO (via toJSON)
BigIntlève TypeError

Pour la liste complète des différences entre JSON et objets JavaScript, voir JSON vs objets JavaScript.

Pièges courants

Les références circulaires lèvent

const a = {};
a.self = a;
JSON.stringify(a);
// TypeError: Converting circular structure to JSON

// Correctif : un replacer qui suit les objets vus, ou restructurer les données

BigInt n’est pas supporté

JSON.stringify({ id: 9007199254740993n });
// TypeError: Do not know how to serialize a BigInt

// Correctif : convertir en chaîne d’abord, ou ajouter un replacer
JSON.stringify({ id: 9007199254740993n }, (k, v) =>
  typeof v === 'bigint' ? v.toString() : v
);

Les grands entiers perdent en précision à l’aller-retour

Les nombres au-delà de 253 ne peuvent pas être représentés exactement. Si vous stringify puis parsez un grand ID entier, il peut changer. Stockez de tels IDs en chaînes.

APIs voisines : structuredClone, le reviver et Stable Stringify

  • structuredClone —— pour des copies profondes en mémoire, n’utilisez pas JSON.parse(JSON.stringify(x)). structuredClone gère Date, Map, Set, ArrayBuffer et les références circulaires nativement, et est bien plus rapide.
  • L’argument reviver de JSON.parse est le miroir du replacer ici. Couplez-les pour des allers-retours sans perte sur des types que JSON ne modélise pas —— par ex. encoder Date comme chaîne ISO dans replacer et le reconstruire dans reviver.
  • Librairies de stable-stringify (par ex. json-stable-stringify, fast-json-stable-stringify) —— produisent la même chaîne quel que soit l’ordre d’insertion des clés. Utilisez-les quand la sortie est hashée, signée ou comparée comme texte (voir RFC 8785 / JCS pour la version formelle).

Stringify dans d’autres langages

# Python
import json
json.dumps({"name": "Ada"})                       # compact
json.dumps({"name": "Ada"}, indent=2)             # pretty
json.dumps({"name": "Ada"}, separators=(',', ':')) # minifié

// Go
import "encoding/json"
b, _ := json.Marshal(map[string]string{"name": "Ada"})

// Ruby
require 'json'
{ name: "Ada" }.to_json

Stringify du JSON dans votre navigateur

Besoin d’échapper une valeur JSON en un littéral de chaîne —— pour l’embarquer dans du code, une colonne de DB ou une commande shell ? L’outil JSON Stringify de fixjson le fait instantanément, dans votre navigateur, sans envoyer de données à un serveur.

Questions fréquentes

Comment pretty-print avec JSON.stringify ?

Passez un troisième argument : JSON.stringify(value, null, 2) pour 2 espaces, ou '\t' pour des tabulations. Voir Comment formater du JSON.

Pourquoi JSON.stringify supprime-t-il certaines de mes propriétés ?

Les propriétés avec valeurs undefined, fonction ou Symbol sont omises car JSON n’a pas de représentation pour elles. Utilisez un replacer ou convertissez-les d’abord.

Comment stringify une valeur contenant un BigInt ?

JSON.stringify() lève sur BigInt. Fournissez un replacer qui appelle .toString() sur les valeurs bigint, et reparsez-les délibérément de l’autre côté.

Quelle différence entre JSON.stringify et JSON.parse ?

stringify transforme une valeur en chaîne JSON ; parse transforme une chaîne JSON en valeur. Ce sont des inverses. Pour les pièges de parsing, voir Gérer du JSON cassé en JavaScript.

Comment JSON.stringify une Map ou un Set ?

Par défaut, les deux se sérialisent en "{}" —— une Map n’a pas de propriétés propres énumérables et un Set se stringify comme objet vide. Convertissez-les d’abord en une forme JSON-friendly (ou via un replacer) :

// Map → tableau de paires [key, value] (round-trippable)
JSON.stringify([...myMap]);
// ou avec un replacer :
JSON.stringify({ data: myMap }, (k, v) =>
  v instanceof Map ? Object.fromEntries(v) :
  v instanceof Set ? [...v] : v
);

Au retour, reconstruisez avec new Map(arr) / new Set(arr) dans un reviver de JSON.parse, puisque JSON pur n’a pas de types Map/Set.

Essayez maintenant