JSON و تبادل داده

ساختار JSON، JSON.parse و JSON.stringify با reviver و replacer، Serialization و Deserialization، JSON در API، محدودیت‌ها و JSONP.

JSON چیست؟

JSON (JavaScript Object Notation) فرمت سبک متن برای تبادل داده — الهام‌گرفته از اشیا جاوا اسکریپت اما مستقل از زبان:

// JSON معتبر:
{
    "name": "علی",
    "age": 25,
    "active": true,
    "score": null,
    "tags": ["js", "web"],
    "address": {
        "city": "تهران",
        "zip": "12345"
    }
}

قواعد JSON

JSON.stringify — سریال‌سازی

const user = {
    name: "علی",
    age: 25,
    city: "تهران"
};

// به رشته:
const json = JSON.stringify(user);
console.log(json); // {"name":"علی","age":25,"city":"تهران"}
console.log(typeof json); // string

// فاصله‌گذاری — خوانا:
const pretty = JSON.stringify(user, null, 2);
// {
//   "name": "Ali",
//   "age": 25,
//   ...
// }

replacer — فیلتر و تبدیل

// آرایه — فقط این کلیدها:
const filtered = JSON.stringify(user, ["name", "age"]);
// {"name":"علی","age":25}

// تابع — تبدیل مقادیر:
const custom = JSON.stringify(user, (key, value) => {
    if (key === "age") return undefined;  // حذف
    if (typeof value === "string") return value.toUpperCase();
    return value;
});
// {"name":"علی"...}

toJSON — کنترل سریال‌سازی

class Person {
    constructor(name, password) {
        this.name = name;
        this.#password = password;
    }

    toJSON() {
        // فقط فیلدهای امن:
        return { name: this.name };
    }
}

const p = new Person("علی", "secret123");
console.log(JSON.stringify(p)); // {"name":"علی"}

JSON.parse — دی‌سریال‌سازی

const json = '{"name":"علی","age":25}';

const obj = JSON.parse(json);
console.log(obj.name); // علی
console.log(obj.age);  // 25

// خطا در JSON غلط:
try {
    JSON.parse("{name: 'علی'}");  // کلید بدون کوتیشن!
} catch (e) {
    console.log(e.name); // SyntaxError
}

reviver — احیا مقادیر

const json = `{
    "name": "علی",
    "birthday": "2000-05-15T00:00:00.000Z"
}`;

const obj = JSON.parse(json, (key, value) => {
    // تبدیل رشته تاریخ به Date:
    if (key === "birthday") return new Date(value);
    return value;
});

console.log(obj.birthday.getFullYear()); // 2000

مدیریت JSON امن

function safeParse(json, defaultValue = null) {
    try {
        return JSON.parse(json);
    } catch {
        return defaultValue;
    }
}

// از localStorage:
const user = safeParse(localStorage.getItem("user"), {});

// stringify با مدیریت خطا (Circular):
function safeStringify(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;
    });
}

const a = {}; a.self = a;
console.log(safeStringify(a)); // {"self":"[Circular]"}

JSON در API

// ارسال:
const res = await fetch("/api/users", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ name: "علی" })
});

// دریافت:
const data = await res.json();  // خودکار parse

// ذخیره محلی:
localStorage.setItem("cart", JSON.stringify(cartItems));
const cart = JSON.parse(localStorage.getItem("cart") || "[]");

Deep Clone با JSON

const original = {
    name: "علی",
    address: { city: "تهران" },
    scores: [18, 20]
};

// clone عمیق — ساده ولی محدود:
const clone = JSON.parse(JSON.stringify(original));

clone.address.city = "شیراز";
console.log(original.address.city); // تهران — جدا شد!

// محدودیت‌ها: Date → رشته، تابع → حذف، undefined → حذف

محدودیت‌های JSON

نوعدر JSONنتیجه
undefinedپشتیبانی نمی‌شودحذف می‌شود
Functionپشتیبانی نمی‌شودحذف می‌شود
Dateبه رشته ISO"2025-01-15T..."
NaN/Infinityمجاز نیستnull
Map/Setموجود نیست{}
Symbolموجود نیستحذف می‌شود

JSONP — تکنیک قدیمی

قبل از CORS — با تگ script درخواست بین‌دامنه:

// سرور به جای JSON، کد JS برمی‌گرداند:
// callback({"data": "value"});

function handleResponse(data) {
    console.log("دریافت شد:", data);
}

const script = document.createElement("script");
script.src = "https://api.example.com/data?callback=handleResponse";
document.body.appendChild(script);
// → handleResponse({"data": "value"}) اجرا می‌شود
امروزه JSONP منسوخ است — از CORS و fetch استفاده کنید.

جمع‌بندی

کارابزار
شیء به رشتهJSON.stringify(obj, replacer?, space?)
رشته به شیءJSON.parse(str, reviver?)
clone عمیقJSON.parse(JSON.stringify(obj))
ذخیره در localStoragestringify قبل، parse بعد

این مبحث بخشی از دوره آموزش کامل جاوا اسکریپت است.

ابزارهای مرتبط