JSON.stringify(), JSON.parse(), récapitulatif de la semaine
CRUD complet en mémoire avec séparation données/opérations
Utilisez les flèches, cliquez ou glissez pour naviguer
1. Comprendre le format JSON
Règles strictes et différences avec les objets JS
2. Utiliser JSON.stringify()
Sérialiser un objet en chaîne
3. Utiliser JSON.parse()
Désérialiser une chaîne JSON
4. Récapituler la semaine
Objets, méthodes, destructuring, référence vs valeur
5. Graine d'architecture
Séparer les données des opérations
JSON : le format universel
API, fichiers, config - comprendre les règles strictes
JSON.stringify() et JSON.parse()
Sérialiser et désérialiser - le deep clone limité
Récap de la semaine
Objets, méthodes, destructuring, référence vs valeur
Graine d'architecture
Séparer les données des opérations - la base de Clean Architecture
Projet : Carnet de contacts
CRUD immutable avec séparation données/opérations
JavaScript Object Notation
Le format universel d'échange de données
API, fichiers de config, stockage local
Objet JavaScript
const user = {
name: "Alice",
age: 25,
isActive: true,
greet: function() {
return "Hello!"
}
};
Clés sans guillemets, fonctions OK
JSON valide
{
"name": "Alice",
"age": 25,
"isActive": true
}
Clés entre guillemets doubles, pas de fonctions
Types autorisés
string (guillemets doubles)
number
boolean (true/false)
null
array [...]
object {...}
Interdit
fonctions
undefined
commentaires
trailing commas
guillemets simples
Date, RegExp, Map, Set
Les clés DOIVENT être entre guillemets doubles : "key"
// Une liste de contacts
[
{ "nom": "Alice" },
{ "nom": "Bob" }
]
JSON est un format texte - il peut être stocké dans un fichier, envoyé via HTTP, ou sauvegardé dans localStorage
Sérialiser un objet en chaîne JSON
Objet JavaScript -> Chaîne JSON
const obj = { nom: "Alice", age: 25 };
const json = JSON.stringify(obj);
// Résultat : '{"nom":"Alice","age":25}'
Entrée
Un objet JavaScript
Sortie
Une chaîne de caractères JSON
Les fonctions sont ignorées lors de la sérialisation!
const contact = {
nom: "Marie",
email: "[email protected]"
};
const json = JSON.stringify(contact, null, 2);
Le 3ème argument (2) indique l'indentation
Désérialiser une chaîne JSON en objet
Chaîne JSON -> Objet JavaScript
const json = '{"nom":"Alice","age":25}';
const obj = JSON.parse(json);
// obj.nom === "Alice"
Entrée
Une chaîne JSON valide
Sortie
Un objet JavaScript
JSON.parse() lance une erreur si le JSON est mal formé!
const original = { a: 1, b: { c: 2 } };
const clone = JSON.parse(JSON.stringify(original));
// clone est une copie indépendante!
Avantages
Copie profonde automatique
Simple à écrire
Limitations
Perd les fonctions
Perd undefined, Date devient string
Pas de références circulaires
Les concepts objets essentiels
Objets & Méthodes
Destructuring
Référence vs Valeur
Spread Operator
const contact = {
nom: "Alice",
email: "[email protected]",
afficher() {
return `${this.nom} - ${this.email}`;
}
};
Propriétés
Des données stockées
contact.nom, contact.email
Méthodes
Des fonctions dans l'objet
contact.afficher()
const contact = { nom: "Alice", email: "[email protected]", tel: "06..." };
// Extraire des propriétés
const { nom, email } = contact;
// Renommer
const { nom: nomComplet } = contact;
// Valeur par défaut
const { ville = "Paris" } = contact;
Destructuring = extraire rapidement des propriétés d'un objet
Types primitifs (valeur)
let a = 5;
let b = a;
b = 10;
// a vaut toujours 5
Copie indépendante
Objets (référence)
let obj1 = { x: 1 };
let obj2 = obj1;
obj2.x = 99;
// obj1.x vaut 99 aussi!
Même objet en mémoire
Les objets sont passés par référence - modifier l'un modifie l'autre!
const original = { a: 1, b: 2 };
// Shallow copy
const copie = { ...original };
// Ajouter/modifier des propriétés
const modifie = { ...original, c: 3, b: 99 };
Shallow copy = copie superficielle (les objets imbriqués restent partagés)
Séparer les données des opérations
La base de la Clean Architecture
Chaque fonction fait UN seul job
Mauvaise approche
let contacts = [];
// Variable globale
// Fonctions qui la modifient
Difficile à tester, imprévisible
Bonne approche
// Données passées en paramètre
function ajouter(liste, contact) {
return [...liste, contact];
}
Prévisible, testable, réutilisable
// Fonction pure : retourne une NOUVELLE liste
function ajouterContact(liste, nouveauContact) {
return [...liste, nouveauContact];
}
// Utilisation
const ancienneListe = [{ nom: "Alice" }];
const nouvelleListe = ajouterContact(ancienneListe, { nom: "Bob" });
// ancienneListe reste inchangée!
Immutable = on ne modifie jamais, on crée une nouvelle version
Create
[...liste, nouveau]
Read
liste.find(c => c.id === id)
Update
liste.map(c => c.id === id ? {...c, ...data} : c)
Delete
liste.filter(c => c.id !== id)
Chaque opération retourne une NOUVELLE liste sans modifier l'originale
CRUD complet en mémoire
Séparation données / opérations
Architecture propre et testable
Données (data.js)
// État initial
const initialContacts = [
{ id: 1, nom: "Alice", ... }
];
Opérations (operations.js)
function ajouter(liste, contact) {...}
function supprimer(liste, id) {...}
function modifier(liste, id, data) {...}
Séparation claire = code maintenable et testable
function ajouterContact(liste, contact) {
return [...liste, {
id: Date.now(), // ID unique
...contact
}];
}
Retourne une nouvelle liste avec le contact ajouté
L'originale reste inchangée
// Lire tous les contacts
function listerContacts(liste) {
return liste;
}
// Trouver un contact par ID
function trouverContact(liste, id) {
return liste.find(c => c.id === id);
}
find() retourne le premier élément qui correspond
function modifierContact(liste, id, nouvellesDonnees) {
return liste.map(contact =>
contact.id === id
? { ...contact, ...nouvellesDonnees }
: contact
);
}
map() crée un nouveau tableau avec les modifications
Spread pour fusionner les anciennes et nouvelles données
function supprimerContact(liste, id) {
return liste.filter(contact => contact.id !== id);
}
filter() garde uniquement les éléments qui ne correspondent pas à l'ID
// État initial
let contacts = [];
// Ajouter
contacts = ajouterContact(contacts, { nom: "Alice", email: "[email protected]" });
// Modifier
const id = contacts[0].id;
contacts = modifierContact(contacts, id, { nom: "Alice Dupont" });
// Supprimer
contacts = supprimerContact(contacts, id);
On réassigne contacts avec le résultat de chaque opération
Trailing commas interdits
{ "nom": "Alice", }
{ "nom": "Alice" }
Pas de commentaires
{ "nom": "Alice" /* erreur */ }
JSON.parse() lance une erreur si mal formé
Prévoir un try/catch pour la production
Utiliser des variables globales
let contacts = [];
function ajouter(c) {
contacts.push(c);
}
Effets de bord imprévisibles
Passer par paramètre
function ajouter(liste, c) {
return [...liste, c];
}
Prévisible et testable
Insister sur le passage par paramètre - c'est la base de l'architecture propre!
JSON = format strict (guillemets doubles, pas de fonctions)
JSON.parse(JSON.stringify(obj)) = deep clone (mais limité)
Séparer données/opérations = graine de Clean Architecture
Chaque fonction fait UN seul job et reçoit les données en paramètre
JSON
Format universel, règles strictes
Guillemets doubles obligatoires
stringify/parse
Sérialiser / Désérialiser
Technique de deep clone
Immutable
Ne jamais modifier l'original
Créer une nouvelle version
Fonctions pures
Un seul job
Données en paramètre
1. Créer un contact
Utiliser ajouterContact() avec nom, email, téléphone
2. Lister et trouver
Afficher tous les contacts, puis trouver par ID
3. Modifier un email
Utiliser modifierContact() pour changer l'email
4. Supprimer et vérifier
Supprimer un contact et vérifier que la liste est mise à jour
JSON et l'architecture propre sont les fondations du développement moderne
Prochain cours : Persistance avec localStorage