28. JSON (JavaScript Object Notation)
JSON is a lightweight, human-readable text-based data interchange format that is easy for machines to parse. JSON in JavaScript is a subset of object literals — but there are strict rules that must be followed.
Why Is JSON Important?
Almost all data communication on the web uses JSON: REST APIs, localStorage, configuration files, and so on. Mastering JSON is a must for web development.
// JavaScript object — any type allowed
const obj = {
name: "Mike",
age: 20,
active: true,
grade: null,
hobbies: ["coding", "reading"],
address: { city: "New York" },
lahir: new Date() // ← Date, not JSON!
};
// JSON — only basic types
const json = JSON.stringify(obj);
// Date is automatically converted to an ISO string
Code Example
JSON.stringify() — Object to String
const student = {
name: "Mike Johnson",
studentId: "2024001",
major: "Computer Science",
gpa: 3.75,
active: true,
course: ["Algorithms", "Database", "Web Programming"],
address: {
city: "New York",
province: "New York"
}
};
// Basic
const jsonString = JSON.stringify(student);
console.log(typeof jsonString); // "string"
console.log(jsonString);
// '{"name":"Mike Johnson","studentId":"2024001",...}'
// Pretty print (with indentation)
const pretty = JSON.stringify(student, null, 2);
console.log(pretty);
// {
// "name": "Mike Johnson",
// "studentId": "2024001",
// "major": "Computer Science",
// ...
// }
// With a replacer — filter only the properties you want
const ringkas = JSON.stringify(student, ["name", "studentId", "gpa"]);
console.log(ringkas);
// '{"name":"Mike Johnson","studentId":"2024001","gpa":3.75}'
// With a replacer function
const filtered = JSON.stringify(student, (key, value) => {
// Remove properties that start with an underscore (if any)
if (key.startsWith("_")) return undefined;
// Remove large fields
if (key === "address") return undefined;
return value;
}, 2);
JSON.parse() — String to Object
const jsonString = '{"name":"Mike","studentId":"2024001","gpa":3.75}';
// Basic
const object = JSON.parse(jsonString);
console.log(object.name); // "Mike"
console.log(object.gpa); // 3.75
// With a reviver — transform values while parsing
const data = '{"name":"Mike","gpa":"3.75","date":"2026-07-14T00:00:00Z"}';
const objectReviver = JSON.parse(data, (key, value) => {
// Convert the gpa string to a number
if (key === "gpa") return parseFloat(value);
// Convert the date string to a Date
if (key === "date") return new Date(value);
return value;
});
console.log(objectReviver.gpa); // 3.75 (number)
console.log(objectReviver.date instanceof Date); // true
// Error handling
try {
const invalid = JSON.parse("not json");
} catch (error) {
console.error("Invalid JSON:", error.message);
}
Common JSON Patterns
// 1. Save data to localStorage
function saveData(name, data) {
try {
const json = JSON.stringify(data);
localStorage.setItem(name, json);
return true;
} catch (error) {
console.error("Failed to save:", error);
return false;
}
}
// 2. Load data from localStorage
function loadData(name) {
try {
const json = localStorage.getItem(name);
if (json === null) return null;
return JSON.parse(json);
} catch (error) {
console.error("Failed to load:", error);
return null;
}
}
// 3. Deep clone with JSON
const original = {
name: "Mike",
address: { city: "New York" },
course: ["Algorithms"]
};
const clone = JSON.parse(JSON.stringify(original));
clone.address.city = "Chicago";
console.log(original.address.city); // "New York" (unchanged)
// 4. Convert between formats
const csvData = "name,studentId,gpa\nMike,2024001,3.75\nAnna,2024002,3.20";
const lines = csvData.split("\n").slice(1);
const studentArray = lines.map(line => {
const [name, studentId, gpa] = line.split(",");
return { name, studentId, gpa: parseFloat(gpa) };
});
console.log(JSON.stringify(studentArray, null, 2));
Common Mistakes with JSON
// 1. CANNOT parse functions
const obj = { name: "Mike", greet() { return "Hi"; } };
const json = JSON.stringify(obj);
console.log(json); // '{"name":"Mike"}' — the method is gone!
const back = JSON.parse(json);
console.log(back.greet); // undefined
// 2. CANNOT parse undefined
const data = { name: "Mike", age: undefined };
console.log(JSON.stringify(data)); // '{"name":"Mike"}' — undefined is removed
// 3. CANNOT parse Symbols
const obj2 = { id: Symbol("123") };
// JSON.stringify(obj2); // Error!
// 4. CANNOT parse Infinity/NaN
const obj3 = { grade: Infinity, score: NaN };
console.log(JSON.stringify(obj3)); // '{"grade":null,"score":null}'
// 5. Dates become strings, not Date objects
const obj4 = { time: new Date() };
const parsed = JSON.parse(JSON.stringify(obj4));
console.log(parsed.time instanceof Date); // false! (it's a string)
// Solution: use a reviver to convert dates
const withDate = JSON.parse(
JSON.stringify(obj4),
(key, value) => key === "time" ? new Date(value) : value
);
console.log(withDate.time instanceof Date); // true
JSON with the Fetch API
async function students() {
try {
// GET — fetch data
const response = await fetch("/api/student", {
method: "GET",
headers: {
"Content-Type": "application/json"
}
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json(); // automatic JSON.parse
return data;
} catch (error) {
console.error("Failed to fetch data:", error);
return [];
}
}
async function addStudent(student) {
try {
const response = await fetch("/api/student", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(student) // automatic JSON.stringify
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return await response.json();
} catch (error) {
console.error("Failed to add data:", error);
return null;
}
}
Code Explanation
| Function | Explanation |
|---|---|
JSON.stringify(obj, replacer, space) |
Convert an object to a JSON string |
JSON.parse(string, reviver) |
Convert a JSON string to an object |
replacer |
An array of properties or a function to filter/transform while stringifying |
reviver |
A function to transform values while parsing |
try-catch |
Required to handle invalid JSON |
What JSON CANNOT Handle
❌ Function → lost during stringify
❌ undefined → lost during stringify
❌ Symbol → error during stringify
❌ Infinity → becomes null
❌ NaN → becomes null
❌ Date → becomes an ISO string (not a Date object)
❌ RegExp → becomes an empty object {}
Real-World Examples
A grade notes system using localStorage:
class CampusNotes {
constructor() {
this.key = "campus_data";
this.data = this.muat();
}
muat() {
try {
const json = localStorage.getItem(this.key);
return json ? JSON.parse(json) : { student: [], course: [] };
} catch {
return { student: [], course: [] };
}
}
save() {
try {
localStorage.setItem(this.key, JSON.stringify(this.data, null, 2));
return true;
} catch (error) {
console.error("Failed to save:", error);
return false;
}
}
addStudent(name, studentId, major) {
const new = {
id: Date.now(),
name,
studentId,
major,
grade: {},
created: new Date().toISOString()
};
this.data.student.push(new);
this.save();
return new;
}
inputGrade(studentId, courseCode, grade) {
const student = this.data.student.find(m => m.studentId === studentId);
if (!student) return { success: false, message: "Student not found" };
student.grade[courseCode] = grade;
this.save();
return { success: true, message: `Grade ${grade} added for ${student.name}` };
}
printTranscript(studentId) {
const student = this.data.student.find(m => m.studentId === studentId);
if (!student) return "Student not found";
let transcript = `\n=== Transcript Grade ===\n`;
transcript += `Name: ${student.name}\nStudentID: ${student.studentId}\nMajor: ${student.major}\n\n`;
const entries = Object.entries(student.grade);
if (entries.length === 0) {
transcript += "None yet grade.\n";
} else {
let total = 0;
for (const [mk, grade] of entries) {
transcript += `${mk}: ${grade}\n`;
total += grade;
}
const average = (total / entries.length).toFixed(2);
transcript += `\nAverage: ${average}\n`;
}
return transcript;
}
eksporJSON() {
const json = JSON.stringify(this.data, null, 2);
const blob = new Blob([json], { type: "application/json" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = `campus_backup_${new Date().toISOString().slice(0, 10)}.json`;
a.click();
URL.revokeObjectURL(url);
}
}
// Usage
const catatan = new CampusNotes();
catatan.addStudent("Mike Johnson", "2024001", "Computer Science");
catatan.addStudent("Anna Reed", "2024002", "Information Systems");
catatan.inputGrade("2024001", "IF101_Algoritma", 85);
catatan.inputGrade("2024001", "IF102_Database", 90);
catatan.inputGrade("2024002", "SI101_Accounting", 88);
console.log(catatan.printTranscript("2024001"));
// === Transcript Grade ===
// Name: Mike Johnson
// StudentID: 2024001
// Major: Computer Science
//
// IF101_Algoritma: 85
// IF102_Database: 90
//
// Average: 87.50
// Export to a JSON file
catatan.eksporJSON();
Conclusion
JSON.stringify()converts an object to a JSON string — usenull, 2for pretty printing.JSON.parse()converts a JSON string to an object — always wrap it intry-catch.- A replacer filters properties while stringifying, and a reviver transforms values while parsing.
- JSON doesn't support
function,undefined,Symbol,Date(becomes a string), andInfinity. - localStorage only stores strings — always stringify before saving and parse when loading.