JavaScript JSON
JSON (JavaScript Object Notation) is a lightweight data interchange format that is easy for humans to read and write, and easy for machines to parse and generate. JSON is widely used in modern web development for data transmission between clients and servers.
What is JSON
JSON is a text-based data interchange format based on JavaScript object literal syntax but independent of JavaScript. Key features:
- Lightweight: More concise than XML
- Human Readable: Text format that's easy to read
- Wide Support: Almost all programming languages have JSON libraries
- Structured: Supports complex data structures
javascript
// JSON object example
const jsonString = `{
"name": "John",
"age": 25,
"isStudent": true,
"hobbies": ["reading", "swimming", "coding"],
"address": {
"city": "New York",
"street": "123 Main St"
}
}`;
console.log(typeof jsonString); // "string"JSON Syntax Rules
Basic Syntax
javascript
// Valid JSON format
const validJson = `{
"name": "John",
"age": 25,
"isActive": true,
"salary": null,
"hobbies": ["reading", "swimming"],
"address": {
"city": "New York",
"zipcode": "10001"
}
}`;
// Invalid JSON (JavaScript object literal)
// Keys must use double quotes
// Single quotes not allowed
// undefined and functions not validJSON Data Types
javascript
// String
const jsonString = `"Hello World"`;
// Number
const jsonNumber = `42`;
const jsonFloat = `3.14159`;
// Boolean
const jsonBoolean = `true`;
// null
const jsonNull = `null`;
// Object
const jsonObject = `{ "name": "John", "age": 25 }`;
// Array
const jsonArray = `["apple", "banana", "orange"]`;
// Nested structure
const complexJson = `{
"users": [
{ "id": 1, "name": "John" },
{ "id": 2, "name": "Jane" }
],
"total": 2
}`;JSON Object Methods
JSON.parse() - Parse JSON String
javascript
// Basic parsing
const jsonString = `{ "name": "John", "age": 25, "isStudent": true }`;
const obj = JSON.parse(jsonString);
console.log(obj.name); // "John"
console.log(obj.age); // 25
console.log(obj.isStudent); // true
// Parse array
const jsonArray = `["apple", "banana", "orange"]`;
const fruits = JSON.parse(jsonArray);
console.log(fruits[0]); // "apple"
// With reviver parameter
const userData = `{ "name": "John", "birthDate": "1990-01-01", "salary": "5000" }`;
const parsedUser = JSON.parse(userData, (key, value) => {
if (key === "birthDate") {
return new Date(value);
}
if (key === "salary") {
return Number(value);
}
return value;
});
console.log(parsedUser.birthDate instanceof Date); // true
console.log(typeof parsedUser.salary); // "number"JSON.stringify() - Serialize to JSON String
javascript
// Basic serialization
const obj = { name: "John", age: 25, isStudent: true };
const jsonString = JSON.stringify(obj);
console.log(jsonString); // {"name":"John","age":25,"isStudent":true}
// With replacer parameter (filter properties)
const user = {
name: "John",
age: 25,
password: "secret123",
email: "john@example.com"
};
// Only serialize specified properties
const publicData = JSON.stringify(user, ["name", "age", "email"]);
console.log(publicData); // {"name":"John","age":25,"email":"john@example.com"}
// Use function replacer
const filteredData = JSON.stringify(user, (key, value) => {
if (key === "password") {
return undefined; // Exclude password
}
return value;
});
// Formatted output
const formattedJson = JSON.stringify(obj, null, 2);
console.log(formattedJson);
/*
{
"name": "John",
"age": 25,
"isStudent": true
}
*/toJSON() Method
Objects can define toJSON() to customize serialization:
javascript
class User {
constructor(name, birthDate) {
this.name = name;
this.birthDate = birthDate;
}
toJSON() {
return {
name: this.name,
age: this.getAge(),
birthDate: this.birthDate.toISOString().split("T")[0]
};
}
getAge() {
const today = new Date();
const birth = new Date(this.birthDate);
return today.getFullYear() - birth.getFullYear();
}
}
const user = new User("John", new Date("1990-01-01"));
console.log(JSON.stringify(user)); // {"name":"John","age":34,"birthDate":"1990-01-01"}JSON Limitations
Unsupported Types
javascript
const obj = {
func: function() { return "hello"; }, // Functions
undef: undefined, // undefined
sym: Symbol("id"), // Symbol
date: new Date(), // Date object
regex: /abc/g // RegExp
};
const json = JSON.stringify(obj);
console.log(json); // {"date":"2024-01-01T00:00:00.000Z"}
// Functions, undefined, Symbol are ignored; Date converted to stringCircular Reference
javascript
const obj = { name: "John" };
obj.self = obj; // Circular reference
try {
const json = JSON.stringify(obj);
} catch (error) {
console.log("Serialization error:", error.message);
// "Converting circular structure to JSON"
}
// Handle circular references
function stringifyWithCircular(obj) {
const seen = new WeakSet();
return JSON.stringify(obj, (key, value) => {
if (typeof value === "object" && value !== null) {
if (seen.has(value)) {
return "[Circular]";
}
seen.add(value);
}
return value;
});
}Deep Copy with JSON
javascript
// Deep copy using JSON (has limitations)
const original = {
name: "John",
age: 25,
hobbies: ["reading", "swimming"],
address: { city: "New York", street: "Main St" }
};
const copy = JSON.parse(JSON.stringify(original));
copy.name = "Jane";
copy.hobbies.push("coding");
console.log(original.name); // "John" (unchanged)
console.log(original.hobbies); // ["reading", "swimming"] (unchanged)
// Limitation: Functions and Dates are lost
const objWithFunc = {
name: "John",
greet: function() { return "Hello"; },
date: new Date()
};
const jsonCopy = JSON.parse(JSON.stringify(objWithFunc));
console.log(jsonCopy.greet); // undefined (function lost)
console.log(jsonCopy.date instanceof Date); // false (becomes string)Web Development Applications
AJAX Data Transmission
javascript
// Send JSON data
async function sendUserData(userData) {
try {
const response = await fetch("/api/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(userData)
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
console.error("Failed to send data:", error);
throw error;
}
}
// Receive JSON data
async function fetchUsers() {
try {
const response = await fetch("/api/users");
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return await response.json();
} catch (error) {
console.error("Failed to fetch users:", error);
throw error;
}
}Local Storage
javascript
// Storage manager for complex objects
class StorageManager {
static save(key, data) {
try {
localStorage.setItem(key, JSON.stringify(data));
return true;
} catch (error) {
console.error("Failed to save:", error);
return false;
}
}
static load(key) {
try {
const jsonString = localStorage.getItem(key);
if (jsonString === null) return null;
return JSON.parse(jsonString);
} catch (error) {
console.error("Failed to load:", error);
return null;
}
}
static remove(key) {
localStorage.removeItem(key);
}
}
// Usage
const preferences = { theme: "dark", language: "en-US", notifications: true };
StorageManager.save("userPreferences", preferences);
const loaded = StorageManager.load("userPreferences");
console.log(loaded); // { theme: "dark", language: "en-US", notifications: true }Best Practices
1. Error Handling
javascript
// Safe JSON parse
function safeJsonParse(str, defaultValue = null) {
try {
return JSON.parse(str);
} catch (error) {
console.warn("JSON parse failed:", error.message);
return defaultValue;
}
}
// Safe JSON stringify
function safeJsonStringify(obj, defaultValue = "{}") {
try {
return JSON.stringify(obj);
} catch (error) {
console.warn("JSON stringify failed:", error.message);
return defaultValue;
}
}
// Usage
const invalidJson = '{"name":"John",}'; // Invalid
const parsed = safeJsonParse(invalidJson, {});
console.log(parsed); // {}2. Data Validation
javascript
// Simple JSON Schema validation
class JsonValidator {
static validate(data, schema) {
const errors = [];
for (const [key, rules] of Object.entries(schema)) {
const value = data[key];
// Required validation
if (rules.required && (value === undefined || value === null)) {
errors.push(`Field "${key}" is required`);
continue;
}
if (value !== undefined) {
// Type validation
if (rules.type && typeof value !== rules.type) {
errors.push(`Field "${key}" should be ${rules.type}`);
}
// String validation
if (typeof value === "string") {
if (rules.minLength && value.length < rules.minLength) {
errors.push(`Field "${key}" min length is ${rules.minLength}`);
}
if (rules.maxLength && value.length > rules.maxLength) {
errors.push(`Field "${key}" max length is ${rules.maxLength}`);
}
}
// Number validation
if (typeof value === "number") {
if (rules.min !== undefined && value < rules.min) {
errors.push(`Field "${key}" min value is ${rules.min}`);
}
if (rules.max !== undefined && value > rules.max) {
errors.push(`Field "${key}" max value is ${rules.max}`);
}
}
}
}
return { valid: errors.length === 0, errors };
}
}
// Usage
const userData = { name: "John", age: 25, email: "john@example.com" };
const userSchema = {
name: { required: true, type: "string", minLength: 2 },
age: { required: true, type: "number", min: 0, max: 150 },
email: { required: true, type: "string" }
};
const validation = JsonValidator.validate(userData, userSchema);
console.log("Validation result:", validation);3. Configuration Manager
javascript
class ConfigManager {
constructor() {
this.config = this.loadDefaultConfig();
this.loadStoredConfig();
}
loadDefaultConfig() {
return {
apiUrl: "https://api.example.com",
timeout: 5000,
retries: 3,
debug: false
};
}
loadStoredConfig() {
const stored = localStorage.getItem("appConfig");
if (stored) {
try {
const parsed = JSON.parse(stored);
this.config = { ...this.config, ...parsed };
} catch (error) {
console.error("Failed to load config:", error);
}
}
}
getConfig(key = null) {
return key ? this.config[key] : this.config;
}
setConfig(key, value) {
this.config[key] = value;
this.saveConfig();
}
saveConfig() {
try {
localStorage.setItem("appConfig", JSON.stringify(this.config));
} catch (error) {
console.error("Failed to save config:", error);
}
}
resetConfig() {
this.config = this.loadDefaultConfig();
localStorage.removeItem("appConfig");
}
}
// Usage
const config = new ConfigManager();
console.log(config.getConfig("apiUrl")); // "https://api.example.com"
config.setConfig("debug", true);Summary
Key points about JavaScript JSON:
- Basic Concept: Lightweight data interchange format based on JS object syntax
- Syntax Rules: Strict key-value format, keys must use double quotes
- Core Methods: JSON.parse() for parsing, JSON.stringify() for serialization
- Data Types: Supports strings, numbers, booleans, null, objects, arrays
- Limitations: No functions, undefined, Symbol, or circular references
- Custom Handling: toJSON() method, replacer and reviver parameters
- Applications: AJAX data transmission, local storage, configuration files
- Best Practices: Error handling, performance optimization, data validation
Mastering JSON handling is fundamental for web development. In the next chapter, we will learn about JavaScript async programming.