JSON و JavaScript Object در نگاه اول بسیار شبیهاند؛ هر دو میتوانند مجموعهای از کلیدها و مقدارها را نمایش دهند و در بسیاری از مثالهای ساده تقریباً یکسان بهنظر میرسند. بااینحال این شباهت ظاهری باعث یکی از رایجترین اشتباهها در توسعه وب میشود: JSON یک قالب متنی مستقل برای تبادل داده است، اما Object جاوااسکریپت یک ساختار زنده در حافظه برنامه محسوب میشود. تفاوت این دو فقط در کوتیشن یا ظاهر Syntax خلاصه نمیشود و روی Parse، Serialization، نوع دادهها، امنیت، انتقال شبکه و رفتار Runtime اثر مستقیم دارد.
Quick Answer: JSON یک متن استاندارد برای نمایش داده است، در حالی که JavaScript Object یک مقدار واقعی در حافظه Runtime است. JSON فقط نوعهای String، Number، Boolean، null، Object و Array را پشتیبانی میکند؛ اما Object جاوااسکریپت میتواند Function، Date، Map، Set، BigInt، Symbol، undefined، Prototype و رفتارهای پیچیده داشته باشد. برای تبدیل متن JSON به داده ازJSON.parseو برای تبدیل داده سازگار به JSON ازJSON.stringifyاستفاده میشود.
JSON و JavaScript Object چه تفاوتی دارند؟
JSON مخفف JavaScript Object Notation است، اما این نام به معنی یکسانبودن JSON با Object جاوااسکریپت نیست. JSON از Syntax اشیای قدیمی جاوااسکریپت الهام گرفته، ولی بهعنوان یک قالب مستقل و محدود طراحی شده است تا داده بین زبانها، سرویسها و سیستمهای مختلف جابهجا شود. در مقابل، Object جاوااسکریپت بخشی از مدل اجرایی خود زبان است و میتواند داده و رفتار را همزمان نگه دارد.
| ویژگی | JSON | JavaScript Object |
|---|---|---|
| ماهیت | متن | مقدار در حافظه |
| هدف اصلی | تبادل و ذخیره داده | مدلسازی داده و رفتار برنامه |
| کلیدها | حتماً String با کوتیشن دوتایی | String یا Symbol؛ کوتیشن همیشه لازم نیست |
| نوعهای مجاز | محدود به نوعهای JSON | تمام نوعهای JavaScript |
| Function | مجاز نیست | مجاز است |
| Comment | مجاز نیست | در کد مجاز است |
| Prototype | ندارد | دارد |
| Parse لازم است؟ | برای تبدیل متن به داده بله | خیر، از ابتدا داده اجرایی است |
یک مثال ظاهراً مشابه
نمونه زیر یک Object جاوااسکریپت است:
const user = {
name: "Sara",
age: 31,
active: true
};
و نمونه زیر JSON معتبر است:
{
"name": "Sara",
"age": 31,
"active": true
}
هر دو نمونه داده مشابهی دارند، اما اولی بخشی از کد جاوااسکریپت است و دومی متن JSON. در Object، نام کلیدهای ساده میتواند بدون کوتیشن نوشته شود؛ در JSON تمام کلیدها باید String و داخل کوتیشن دوتایی باشند.
تفاوت در کلیدها
در JSON، کلید Object فقط String است و باید با کوتیشن دوتایی نوشته شود. استفاده از کوتیشن تکی، کلید بدون کوتیشن یا Symbol باعث نامعتبرشدن JSON میشود.
{
"firstName": "Ali",
"city": "Tehran"
}
اما در JavaScript Object حالتهای زیر معتبرند:
const token = Symbol("token");
const profile = {
firstName: "Ali",
"home-city": "Tehran",
[token]: "private-value"
};
کلید Symbol در JSON وجود ندارد. هنگام Stringify نیز Propertyهایی با کلید Symbol نادیده گرفته میشوند.
تفاوت در نوع دادهها
JSON فقط شش گروه اصلی مقدار را میپذیرد: String، Number، Boolean، null، Object و Array. JavaScript علاوه بر اینها نوعها و ساختارهای بیشتری دارد؛ مانند undefined، BigInt، Symbol، Function، Date، Map، Set، RegExp، Error، TypedArray و نمونههای کلاس.
| مقدار JavaScript | در JSON مجاز است؟ | رفتار رایج هنگام JSON.stringify |
|---|---|---|
| String | بله | حفظ میشود |
| Number محدود | بله | حفظ میشود |
| NaN و Infinity | خیر | معمولاً به null تبدیل میشوند |
| undefined | خیر | در Object حذف و در Array به null تبدیل میشود |
| Function | خیر | در Object حذف میشود |
| BigInt | خیر | بهطور پیشفرض خطا میدهد |
| Date | نوع مستقل ندارد | معمولاً به String تبدیل میشود |
| Map و Set | نوع مستقل ندارند | بدون تبدیل سفارشی معمولاً خروجی مطلوب نمیدهند |
undefined در JSON وجود ندارد
وجود نداشتن undefined یکی از مهمترین تفاوتهاست. در Object جاوااسکریپت، یک Property میتواند وجود داشته باشد و مقدارش undefined باشد؛ اما JSON چنین مقداری ندارد.
const source = {
name: "Sara",
nickname: undefined
};
console.log(JSON.stringify(source));
// {"name":"Sara"}
Property دوم حذف شده است. این رفتار میتواند در APIها مهم باشد؛ حذف Property با ارسال مقدار null یکسان نیست. null معمولاً یعنی مقدار عمداً خالی است، در حالی که نبودن Property ممکن است به معنی «تغییری اعمال نکن» یا «داده ارسال نشده» باشد.
Function و رفتار در Object
Object جاوااسکریپت فقط محل نگهداری داده نیست و میتواند Method داشته باشد:
const account = {
balance: 500,
deposit(amount) {
this.balance += amount;
}
};
JSON امکان نگهداری Function یا اجرای رفتار را ندارد. این محدودیت عمدی است؛ JSON برای تبادل داده طراحی شده، نه انتقال کد اجرایی. هنگام Stringify، Functionها معمولاً حذف میشوند.
Prototype و وراثت
هر Object جاوااسکریپت میتواند Prototype داشته باشد و Property یا Method را از زنجیره Prototype دریافت کند. JSON چنین مفهومی ندارد و فقط Propertyهای دادهای را نمایش میدهد. پس از Parse کردن JSON، یک Object معمولی ساخته میشود، اما اطلاعات کلاس، Prototype سفارشی و Methodهای نمونه بازسازی نمیشوند.
class User {
constructor(name) {
this.name = name;
}
greet() {
return `Hello ${this.name}`;
}
}
const original = new User("Sara");
const restored = JSON.parse(JSON.stringify(original));
console.log(restored instanceof User); // false
console.log(typeof restored.greet); // undefined
Date در JSON چگونه نمایش داده میشود؟
JavaScript نوع Date دارد، اما JSON نوع تاریخ ندارد. هنگام Stringify، Date معمولاً با متد toJSON به String استاندارد تبدیل میشود.
const event = {
createdAt: new Date("2026-08-06T10:30:00Z")
};
const text = JSON.stringify(event);
// {"createdAt":"2026-08-06T10:30:00.000Z"}
پس از Parse، مقدار createdAt یک String است، نه Date. برای بازسازی Date باید آن را صریحاً تبدیل کرد یا از Reviver استفاده کرد.
const restored = JSON.parse(text, (key, value) => {
if (key === "createdAt") return new Date(value);
return value;
});
تفاوت در Number
JSON نوع Number دارد، اما جزئیات دقت عددی به زبان مقصد وابسته است. JavaScript همه Numberهای معمول را بهصورت عدد ممیز شناور دقت دوگانه نگه میدارد. شناسههای صحیح بسیار بزرگ ممکن است هنگام Parse دقت خود را از دست بدهند.
const text = '{"id":9007199254740993}';
const data = JSON.parse(text);
console.log(data.id);
برای شناسههای بزرگ بهتر است مقدار بهصورت String ارسال شود یا Parser مناسب عددهای بزرگ استفاده شود. همچنین JSON مقادیر NaN، Infinity و -Infinity را نمیپذیرد.
کوتیشن و Syntax معتبر
Object Literal جاوااسکریپت میتواند از کوتیشن تکی، Template Literal در مقدارها، کلیدهای محاسبهشده و کامای انتهایی استفاده کند. JSON محدودتر است.
const settings = {
theme: 'dark',
[getKey()]: true,
};
این کد JavaScript معتبر است، اما JSON نیست. نسخه JSON باید کلیدها و Stringها را با کوتیشن دوتایی بنویسد و کامای انتهایی نداشته باشد.
Comment در JSON مجاز نیست
در فایل JavaScript میتوان Comment نوشت، اما JSON استاندارد Comment ندارد.
const config = {
// user interface theme
theme: "dark"
};
قرار دادن همین Comment در فایل JSON باعث خطای Parse میشود. برخی فرمتهای نزدیک مانند JSONC Comment را میپذیرند، اما آنها JSON استاندارد نیستند و نباید بدون توافق سیستم استفاده شوند.
JSON.parse چه کاری انجام میدهد؟
JSON.parse یک String JSON معتبر را به مقدار JavaScript تبدیل میکند.
const text = '{"name":"Sara","roles":["editor"]}';
const data = JSON.parse(text);
console.log(data.name);
console.log(Array.isArray(data.roles));
Parse کردن فقط Syntax را بررسی میکند و تضمینی درباره Schema، Required بودن فیلدها یا معتبر بودن مقدارهای تجاری نمیدهد. برای این هدف به JSON Schema یا Validation جداگانه نیاز است.
JSON.stringify چه کاری انجام میدهد؟
JSON.stringify یک مقدار سازگار با JSON را به متن JSON تبدیل میکند.
const data = {
name: "Sara",
roles: ["editor", "reviewer"]
};
const compact = JSON.stringify(data);
const pretty = JSON.stringify(data, null, 2);
همه Objectها بدون تغییر قابل Stringify نیستند. Circular Reference، BigInt و نوعهای سفارشی ممکن است به خطا یا خروجی ناقص منجر شوند.
Circular Reference
Object جاوااسکریپت میتواند به خودش یا Object دیگری در یک چرخه اشاره کند، اما JSON یک ساختار درختی است و مرجع چرخهای ندارد.
const node = { name: "root" };
node.self = node;
JSON.stringify(node); // TypeError
برای انتقال Graphهای دارای Reference باید قرارداد سفارشی، شناسههای مرجع یا Serializer تخصصی تعریف شود.
Map و Set
Map و Set ساختارهای بومی JavaScript هستند، اما JSON نوع مستقلی برای آنها ندارد. تبدیل مستقیم آنها معمولاً اطلاعات را حفظ نمیکند.
const map = new Map([["theme", "dark"]]);
console.log(JSON.stringify(map)); // {}
برای Map میتوان از Object.fromEntries یا Array زوجها استفاده کرد. Set نیز معمولاً با Array.from تبدیل میشود.
تبدیل صحیح Object به JSON
- مشخص کنید کدام Propertyها واقعاً باید منتقل شوند.
- نوعهای ناسازگار مانند Date، Map، Set و BigInt را صریحاً تبدیل کنید.
- برای Circular Reference راهبرد مشخص داشته باشید.
- خروجی را با
JSON.stringifyبسازید، نه با اتصال دستی Stringها. - در سمت مقصد، پس از Parse داده را با Schema اعتبارسنجی کنید.
روش اشتباه: ساخت JSON با String Concatenation
const json = '{"name":"' + userInput + '"}';
این روش در برابر کوتیشن، Backslash، خط جدید و ورودیهای کنترلنشده شکننده است. روش امن:
const json = JSON.stringify({ name: userInput });
JSON با Object نمایشدادهشده در Console یکی نیست
Console مرورگر Object را بهشکل تعاملی نشان میدهد و ممکن است بعداً مقدار فعلی آن را نمایش دهد، نه Snapshot لحظه Log. متن JSON ثابت است. برای ثبت Snapshot قابل مقایسه میتوان از JSON.stringify استفاده کرد، البته با آگاهی از محدودیت نوعها.
امنیت: JSON را با eval اجرا نکنید
از eval برای Parse کردن JSON استفاده نکنید. JSON داده است، نه کد. JSON.parse Syntax محدود JSON را میپذیرد و انتخاب مناسبتری است.
const data = JSON.parse(untrustedText);
پس از Parse نیز باید از آلودگی Prototype، Mass Assignment و اعتماد بیقید به فیلدهای ورودی جلوگیری شود. معتبر بودن Syntax به معنی امن یا قابل اعتماد بودن محتوا نیست.
مقایسه صحیح و غلط
| نمونه | JSON معتبر؟ | JavaScript Object معتبر؟ |
|---|---|---|
{"name":"Sara"} | بله | بله، بهعنوان Object Literal |
{name:"Sara"} | خیر | بله |
{'name':'Sara'} | خیر | بله |
{"value":undefined} | خیر | بله |
{"run":function(){}} | خیر | بله |
{"items":[1,2,]} | خیر | در JavaScript معمولاً بله |
چه زمانی از JSON استفاده کنیم؟
- ارسال داده در API
- ذخیره تنظیمات و Snapshotهای ساده
- تبادل داده بین زبانها و سرویسها
- ثبت Event و Message در سیستمهای صف
- ذخیره ساختارهای بدون رفتار و بدون Reference چرخهای
چه زمانی Object جاوااسکریپت مناسبتر است؟
- مدلسازی وضعیت زنده برنامه
- نگهداری Method و رفتار
- استفاده از Date، Map، Set یا کلاسها
- کار با Prototype و Getter/Setter
- ایجاد Referenceهای مشترک یا چرخهای در حافظه
خطاهای رایج
فرض اینکه هر Object مستقیماً JSON است
Object فقط زمانی بدون مشکل Serialize میشود که مقدارهایش با مدل داده JSON سازگار باشند.
استفاده از JSON.parse روی Object
JSON.parse ورودی String میخواهد. اگر داده از قبل Object است، نیازی به Parse ندارد.
استفاده از JSON.stringify برای Deep Clone عمومی
این روش Date، undefined، Function، Map، Set، Prototype و Referenceهای مشترک را از بین میبرد و برای همه دادهها مناسب نیست.
اعتماد به JSON.stringify برای امنیت
Stringify فقط Serialization است و داده محرمانه را رمزنگاری یا ورودی را معتبر نمیکند.
نادیدهگرفتن دقت عددهای بزرگ
شناسههای بزرگ ممکن است در JavaScript دقت خود را از دست بدهند. برای چنین مقادیری String یا Parser تخصصی لازم است.
بهترین روشها
- JSON را متن و Object را مقدار اجرایی در نظر بگیرید.
- برای Parse فقط از Parser استاندارد استفاده کنید.
- برای ساخت JSON از Serializer استفاده کنید.
- قبل از Serialization نوعهای ناسازگار را صریحاً تبدیل کنید.
- بعد از Parse، داده را با Schema و قواعد تجاری بررسی کنید.
- تفاوت نبودن Property و null را در قرارداد API مشخص کنید.
- برای Date و عددهای بزرگ قرارداد شفاف داشته باشید.
- از eval برای JSON استفاده نکنید.
چکلیست تشخیص JSON از Object
- آیا داده داخل String قرار دارد؟ احتمالاً JSON است.
- آیا کلید بدون کوتیشن یا با کوتیشن تکی نوشته شده؟ JSON استاندارد نیست.
- آیا Function، undefined یا Symbol وجود دارد؟ Object جاوااسکریپت است.
- آیا Comment یا کامای انتهایی وجود دارد؟ JSON معتبر نیست.
- آیا داده باید بین زبانهای مختلف منتقل شود؟ JSON گزینه رایجتری است.
- آیا Prototype یا Method باید حفظ شود؟ JSON بهتنهایی کافی نیست.
تفاوت در انتقال بین Frontend و Backend
در ارتباط Frontend و Backend، Object جاوااسکریپت مستقیماً از مرز شبکه عبور نمیکند. کلاینت ابتدا داده را Serialize میکند و معمولاً متن JSON در بدنه درخواست قرار میگیرد. سرور نیز این متن را Parse کرده و آن را به ساختار داده زبان خودش تبدیل میکند. بنابراین چیزی که در DevTools بهعنوان Object میبینید، لزوماً همان فرم دقیق بایتهای ارسالشده نیست. Header محتوا، Encoding، محدودیت حجم، مدیریت خطا و قرارداد Schema همگی بخشی از این مسیر هستند. برای جلوگیری از ناسازگاری، نوع فیلدها، مقادیر null، قالب تاریخ، دقت عددها و رفتار فیلدهای اختیاری باید در قرارداد API مشخص شوند. همچنین بهتر است پاسخ سرور فقط داده لازم را برگرداند و اطلاعات داخلی Object، Methodها یا Propertyهای حساس هرگز صرفاً به دلیل وجود در حافظه Serialize نشوند.
تفاوت در مقایسه و برابری
دو متن JSON ممکن است از نظر فاصله، ترتیب کلیدها یا شکل Escape متفاوت باشند ولی پس از Parse داده معادل تولید کنند. در مقابل، برابری Object در JavaScript معمولاً بر پایه Reference بررسی میشود. دو Object با Propertyهای یکسان الزاماً با عملگر برابری برابر نیستند. برای مقایسه معنایی باید ساختار و مقدارها بررسی شوند؛ Stringify ساده نیز در حضور ترتیب متفاوت کلیدها، نوعهای ناسازگار یا Circular Reference راهحل عمومی نیست. این تفاوت در تست Snapshot، Cache Key، Diff و امضای داده اهمیت زیادی دارد.
جمعبندی
JSON و JavaScript Object ظاهر مشابهی دارند، اما نقش و قابلیتهای متفاوتی ایفا میکنند. JSON یک نمایش متنی محدود و مستقل برای تبادل داده است؛ Object جاوااسکریپت یک ساختار زنده و غنی در Runtime است که میتواند Method، Prototype، Symbol، Date، Map، Set و Referenceهای پیچیده داشته باشد. تبدیل بین این دو با JSON.parse و JSON.stringify انجام میشود، اما این تبدیل همیشه بدون اتلاف اطلاعات نیست. برای جلوگیری از خطا، نوعهای ناسازگار را شناسایی کنید، قرارداد API را دقیق بنویسید، داده Parseشده را اعتبارسنجی کنید و JSON را هرگز با کد اجرایی یکسان ندانید.