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
- کلیدها حتماً با کوتیشن دوتایی:
"key" - رشتهها فقط دوتایی:
"text"نه'text' - مقادیر: رشته، عدد، بولی، null، آرایه، شیء
- نم可用: تابع، تاریخ (Date)، undefined، Symbol، کامنت
- اشتباه رایج:
{name: "علی"}— کلید بدون کوتیشن ❌
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)) |
| ذخیره در localStorage | stringify قبل، parse بعد |
این مبحث بخشی از دوره آموزش کامل جاوا اسکریپت است.