← JS Mastery | Module 4: Objects & Arrays JSON & Object Cloning
Module 4

JSON & Object Cloning

⏱ 16 min read ● Beginner 🆓 Free

JSON — JavaScript Object Notation

JSON is a text format for representing structured data. It's the universal format for data exchange on the web — APIs return JSON, databases store JSON, config files use JSON. It looks like JavaScript objects but has stricter rules.

// JSON rules:
// - Keys MUST be in double quotes
// - Values can be: string, number, boolean, null, array, object
// - No functions, no undefined, no comments, no trailing commas

// Valid JSON:
const jsonString = '{"name":"Alice","age":30,"active":true,"scores":[95,87,92]}';

// Parse JSON string → JavaScript object:
const user = JSON.parse(jsonString);
console.log(user.name);  // "Alice"
console.log(user.scores[0]);  // 95

// Stringify JavaScript object → JSON string:
const obj = { name: "Bob", age: 25, hobbies: ["coding", "music"] };
const json = JSON.stringify(obj);
console.log(json);  // {"name":"Bob","age":25,"hobbies":["coding","music"]}

// Pretty print with indentation (for logging):
console.log(JSON.stringify(obj, null, 2));
// {
//   "name": "Bob",
//   "age": 25,
//   ...
// }

// What gets lost in JSON serialization:
const complex = {
  fn: function() {},   // functions → undefined (omitted)
  sym: Symbol("id"),   // symbols → undefined (omitted)  
  und: undefined,      // undefined values → omitted
  inf: Infinity,       // Infinity → null
  date: new Date()     // Date → string (ISO format)
};

Object Cloning

// Shallow copy methods:
const original = { a: 1, b: { c: 2 } };

const spread = { ...original };
const assign = Object.assign({}, original);

// Both are SHALLOW — nested objects are still shared:
spread.a = 99;      // doesn't affect original
spread.b.c = 99;    // DOES affect original! (same reference)

// Deep clone with structuredClone (modern, ES2022):
const deepClone = structuredClone(original);
deepClone.b.c = 99;  // doesn't affect original!
console.log(original.b.c);  // 2 — safe!

// structuredClone handles: objects, arrays, Date, Map, Set, etc.
// Does NOT handle: functions, DOM nodes, class instances' methods

// Old deep clone trick (JSON):
const jsonClone = JSON.parse(JSON.stringify(original));
// Works for simple data but loses functions, Dates, etc.

// Arrays:
const arr = [1, [2, 3], { a: 4 }];
const shallowArr = [...arr];      // shallow
const deepArr = structuredClone(arr);  // deep

JSON in Practice

// Saving to localStorage (requires JSON):
const preferences = { theme: "dark", fontSize: 16 };
localStorage.setItem("prefs", JSON.stringify(preferences));

// Reading back:
const saved = localStorage.getItem("prefs");
const prefs = saved ? JSON.parse(saved) : {};

// API responses are JSON:
const response = await fetch("https://api.example.com/data");
const data = await response.json();  // auto-parses JSON

// Error handling for malformed JSON:
function safeParseJSON(str) {
  try {
    return JSON.parse(str);
  } catch (e) {
    console.error("Invalid JSON:", e.message);
    return null;
  }
}

// Custom serialization with replacer:
const withDate = { name: "Alice", created: new Date() };
JSON.stringify(withDate, (key, value) => {
  if (value instanceof Date) return value.toISOString();
  return value;
});

// Custom parsing with reviver:
JSON.parse(jsonStr, (key, value) => {
  if (key === "created") return new Date(value);
  return value;
});

⚡ Key Takeaways

🎯 Practice Exercises

EXERCISE 1

Create a user preferences system using localStorage: save preferences as JSON, load them on startup, and update individual settings without losing others.

EXERCISE 2

Write a function that takes any JS value and returns a "safe JSON" version — converting Dates to ISO strings, removing functions, and replacing undefined with null.

← Map & Set