Parser du JSON en JavaScript est quelque chose que vous ferez des centaines de fois en tant que développeur web. Heureusement, JavaScript dispose d'un support natif — aucune bibliothèque nécessaire. Mais il y a plus de nuances autour de JSON.parse() et JSON.stringify() que ce que la documentation laisse entendre. Voyons ça correctement.

JSON.parse() — Transformer une chaîne en objet

JSON.parse() prend une chaîne formatée en JSON et la convertit en une valeur JavaScript. Cette valeur est généralement un objet ou un tableau, mais peut aussi être une chaîne, un nombre, un booléen ou null :

js
const jsonString = '{"name": "Alice", "age": 30, "active": true}';
const user = JSON.parse(jsonString);

console.log(user.name);    // "Alice"
console.log(user.age);     // 30
console.log(user.active);  // true
console.log(typeof user);  // "object"

Remarquez que l'entrée doit être une chaîne. Une erreur courante est d'essayer de parser une valeur qui est déjà un objet — JSON.parse({}) lève une SyntaxError car il convertit d'abord l'objet en "[object Object]", ce qui n'est pas du JSON valide.

Enveloppez toujours JSON.parse() dans un try/catch

Voici ce que personne ne vous dit : JSON.parse() lance une SyntaxError si l'entrée est du JSON invalide. Si vous parsez des données provenant d'une API, d'une saisie utilisateur ou d'un fichier, vous devriez toujours gérer cette erreur. Une seule réponse malformée peut crasher votre appli si vous ne le faites pas :

js
function safeParseJSON(str) {
  try {
    return { data: JSON.parse(str), error: null };
  } catch (err) {
    return { data: null, error: err.message };
  }
}

const { data, error } = safeParseJSON('{"name": "Alice"}');
if (error) {
  console.error('Invalid JSON:', error);
} else {
  console.log(data.name); // "Alice"
}

// Handles bad input gracefully
const result = safeParseJSON('not json at all');
console.log(result.error); // "Unexpected token 'o', "not json "... is not valid JSON"

J'utilise un wrapper comme celui-ci dans presque tous mes projets. Cela rend la gestion des erreurs cohérente et évite des exceptions non capturées qui remontent jusqu'à votre interface utilisateur.

JSON.stringify() — Transformer un objet en chaîne

JSON.stringify() fait l'inverse : il convertit une valeur JavaScript en chaîne JSON. Vous l'utiliserez lors de l'envoi de données à une API, de la sauvegarde dans le localStorage ou de l'écriture dans un fichier :

js
const user = {
  name: "Bob",
  age: 25,
  roles: ["admin", "editor"],
  password: "secret123" // we'll handle this later
};

// Basic usage
const jsonString = JSON.stringify(user);
// '{"name":"Bob","age":25,"roles":["admin","editor"],"password":"secret123"}'

// Pretty-printed (great for logs and file output)
const prettyJson = JSON.stringify(user, null, 2);
console.log(prettyJson);
// {
//   "name": "Bob",
//   "age": 25,
//   "roles": ["admin", "editor"],
//   "password": "secret123"
// }

Le troisième argument de JSON.stringify() est le niveau d'indentation. Utiliser 2 ou 4 donne une sortie lisible. La valeur par défaut (sans troisième argument) produit du JSON compact et minifié — préférable pour la transmission réseau.

Ce que stringify() omet silencieusement

Voilà qui piège régulièrement les développeurs. JSON.stringify() omet silencieusement certaines valeurs car JSON ne les supporte pas :

js
const data = {
  name: "Alice",
  greet: function() { return "hi"; },   // Functions → dropped
  undef: undefined,                      // undefined → dropped
  sym: Symbol("key"),                    // Symbols → dropped
  nan: NaN,                              // NaN → null
  inf: Infinity,                         // Infinity → null
  date: new Date("2024-01-15")           // Dates → ISO string
};

console.log(JSON.stringify(data, null, 2));
// {
//   "name": "Alice",
//   "nan": null,
//   "inf": null,
//   "date": "2024-01-15T00:00:00.000Z"
// }
// greet, undef, sym are GONE
Attention : Si vous sérialisez un objet avec des valeurs undefined puis le parsez, ces clés seront entièrement absentes. Cela peut provoquer des bugs subtils si votre code vérifie ensuite obj.key === undefined.

Récupérer du JSON depuis une API — Le pattern du monde réel

En pratique, la plupart des parsings JSON se produisent lors de la récupération de données depuis une API. L' API Fetch rend cela simple — response.json() gère le parsing à votre place :

js
async function getUser(userId) {
  try {
    const response = await fetch(`https://api.example.com/users/${userId}`);

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

    const user = await response.json(); // parses JSON automatically
    return user;
  } catch (err) {
    console.error('Failed to fetch user:', err);
    return null;
  }
}

const user = await getUser(42);
if (user) {
  console.log(`Hello, ${user.name}!`);
}

response.json() est essentiellement JSON.parse(await response.text()). Il lance aussi une erreur si le corps de la réponse n'est pas du JSON valide, il vaut donc la peine de le capturer séparément dans du code de production.

Travailler avec des données JSON imbriquées

Le JSON profondément imbriqué est courant dans les vraies APIs. Voici comment le naviguer en toute sécurité sans crasher sur des clés manquantes :

js
const apiResponse = {
  "user": {
    "profile": {
      "address": {
        "city": "Berlin"
      }
    }
  }
};

// Unsafe — throws if any level is undefined
const city1 = apiResponse.user.profile.address.city; // "Berlin"

// Safe with optional chaining (ES2020+) — returns undefined instead of throwing
const city2 = apiResponse?.user?.profile?.address?.city; // "Berlin"
const zip   = apiResponse?.user?.profile?.address?.zip;  // undefined (not a crash)

// With a fallback using nullish coalescing
const country = apiResponse?.user?.profile?.address?.country ?? "Unknown";

L'opérateur de chaînage optionnel (?.) et la coalescence des nuls (??) sont des fonctionnalités JavaScript modernes — toutes deux intégrées à la spécification ECMAScript depuis 2020 — qui rendent le travail avec des structures JSON incertaines bien plus sûr. Utilisez-les librement — elles sont supportées dans tous les navigateurs modernes et Node.js 14+.

Les fonctions replacer et reviver

JSON.stringify() et JSON.parse() acceptent tous deux un second argument qui vous permet de personnaliser la transformation. Ils sont vraiment utiles dans des scénarios réels :

js
// replacer: filter or transform values during stringify
const user = { name: "Alice", password: "s3cr3t", age: 30 };
const safe = JSON.stringify(user, ["name", "age"]); // only include these keys
// '{"name":"Alice","age":30}'  — password is excluded

// reviver: transform values during parse
const dateJson = '{"name": "Alice", "createdAt": "2024-01-15T09:30:00Z"}';
const parsed = JSON.parse(dateJson, (key, value) => {
  if (key === "createdAt") return new Date(value); // convert string to Date
  return value;
});
console.log(parsed.createdAt instanceof Date); // true
console.log(parsed.createdAt.getFullYear());   // 2024

Le pattern reviver est particulièrement utile pour restaurer des objets Date après un aller-retour par JSON, puisque JSON ne dispose pas de type date natif.

Outils utiles

Lors du travail avec JSON dans des projets JavaScript, ces outils font gagner du temps : JSON Formatter pour formater joliment les réponses minifiées d'API, JSON Validator pour vérifier les erreurs de syntaxe, JSON Path pour interroger des champs spécifiques depuis de gros payloads, et JSON Escape quand vous devez embarquer du JSON dans une chaîne. Pour aller plus loin, la référence MDN JSON est excellente.

Pour conclure

JSON.parse() et JSON.stringify() sont les deux fonctions dont vous avez besoin. Les bonnes habitudes à cultiver : toujours envelopper parse() dans un try/catch, utiliser le chaînage optionnel pour l'accès imbriqué, et savoir ce que stringify() omet silencieusement. Maîtrisez ces trois points et vous gérerez 99 % des scénarios JSON réels sans surprises.