JSON في JavaScript: JSON.stringify و JSON.parse
عندما يطلب تطبيق الطقس درجة الحرارة من الخادم، بأي لغة يتفاهمان؟ التطبيق قد يكون مكتوباً بـ JavaScript، والخادم بـ Python أو PHP. يحتاجان إلى صيغة مشتركة يفهمها الجميع. هذه الصيغة هي JSON. ستستخدمها مع كل خادم، وفي حفظ البيانات، وفي ملفات الإعدادات. في هذا الدرس ستتعلم قراءتها وكتابتها.
ما هي JSON؟
Section titled “ما هي JSON؟”JSON اختصار لـ JavaScript Object Notation، أي «طريقة كتابة كائنات JavaScript». هي نص يصف بيانات بشكل يشبه الكائنات التي تعرفها:
{ "name": "سارة", "age": 14, "isStudent": true, "hobbies": ["القراءة", "الرسم"], "address": { "city": "طنطا" }, "phone": null}تخيّل JSON مثل لغة مشتركة في مطار دولي: كل مسافر يتكلم لغته في بلده، لكن اللافتات كلها مكتوبة بلغة واحدة يفهمها الجميع. كل لغات البرمجة تقريباً تعرف كيف تقرأ JSON وتكتبه.
القواعد
Section titled “القواعد”JSON تشبه كائنات JavaScript، لكنها أكثر صرامة:
| القاعدة | صحيح | خطأ |
|---|---|---|
| أسماء الخصائص بين علامتي تنصيص مزدوجتين | "name": "سارة" |
name: "سارة" |
| النصوص بعلامات مزدوجة فقط | "طنطا" |
'طنطا' |
| لا فاصلة بعد آخر عنصر | [1, 2] |
[1, 2,] |
| لا تعليقات | // تعليق |
|
لا دوال ولا undefined |
"f": function() {} |
والأنواع المسموحة ستة فقط: نص، ورقم، وقيمة منطقية، و null، ومصفوفة، وكائن.
من كائن إلى نص: JSON.stringify
Section titled “من كائن إلى نص: JSON.stringify”الكائن يعيش في ذاكرة البرنامج، ولا يمكن إرساله عبر الإنترنت أو حفظه كما هو. نحوّله أولاً إلى نص:
const user = { name: "سارة", age: 14, hobbies: ["القراءة", "الرسم"] };
const text = JSON.stringify(user);console.log(text);console.log(typeof text);{"name":"سارة","age":14,"hobbies":["القراءة","الرسم"]}stringالنتيجة نص من نوع string، مع أنها تشبه الكائن. لم يعد بإمكانك كتابة text.name.
وللحصول على نص منسق سهل القراءة، أضف معاملين: null ثم عدد مسافات الإزاحة:
console.log(JSON.stringify({ name: "سارة", age: 14 }, null, 2));{ "name": "سارة", "age": 14}ما الذي يضيع؟
Section titled “ما الذي يضيع؟”const item = { title: "كتاب", price: undefined, show() { return this.title; },};
console.log(JSON.stringify(item));{"title":"كتاب"}الخصائص التي قيمتها undefined والدوال تُحذف بصمت، لأن JSON للبيانات فقط. وكائنات التاريخ Date تتحول إلى نصوص.
من نص إلى كائن: JSON.parse
Section titled “من نص إلى كائن: JSON.parse”العملية العكسية: تستقبل نصاً من الخادم وتحوّله إلى كائن تتعامل معه:
const received = '{"city":"القاهرة","temp":31,"rainy":false}';
const weather = JSON.parse(received);console.log(weather.city);console.log(weather.temp + 1);console.log(typeof weather);القاهرة32objectبعد parse أصبح عندك كائن حقيقي: تقرأ خصائصه بالنقطة، وأرقامه أرقام حقيقية تُجمع وتُطرح.
JSON.stringify |
JSON.parse |
|
|---|---|---|
| تأخذ | كائناً أو مصفوفة | نصاً |
| تُرجع | نصاً | كائناً أو مصفوفة |
| متى | قبل الإرسال أو الحفظ | بعد الاستقبال أو القراءة |
النص غير الصالح يسبب خطأ
Section titled “النص غير الصالح يسبب خطأ”إذا كان النص لا يتبع قواعد JSON، ترمي JSON.parse خطأ يوقف البرنامج:
try { JSON.parse("{ name: 'سارة' }");} catch (error) { console.log("نص غير صالح:", error.name);}نص غير صالح: SyntaxErrorهذا النص يبدو طبيعياً ككائن JavaScript، لكنه ليس JSON صالحاً: اسم الخاصية بلا علامات تنصيص، والنص بعلامات مفردة.
مصفوفة من الكائنات
Section titled “مصفوفة من الكائنات”أغلب ما يرجعه الخادم مصفوفة كائنات. بعد parse تستخدم معها كل دوال المصفوفات التي تعلمتها:
const response = '[{"title":"قلم","price":5},{"title":"حقيبة","price":250}]';
const items = JSON.parse(response);console.log(items.length);console.log(items.map((item) => item.title));console.log(items.filter((item) => item.price > 100));2[ 'قلم', 'حقيبة' ][ { title: 'حقيبة', price: 250 } ]نسخ عميق لكائن
Section titled “نسخ عميق لكائن”عرفت في الدرس السابق أن النشر ... ينسخ المستوى الأول فقط. للنسخ العميق لكائن فيه كائنات داخلية، توجد دالة مدمجة:
const original = { name: "سارة", address: { city: "طنطا" } };
const deep = structuredClone(original);deep.address.city = "أسوان";
console.log(original.address.city);console.log(deep.address.city);طنطاأسوانوستجد في أكواد قديمة الحيلة JSON.parse(JSON.stringify(obj)). تؤدي نفس الغرض تقريباً، لكنها تفقد التواريخ والدوال و undefined. استخدم structuredClone.
جرّب بنفسك
Section titled “جرّب بنفسك”الناتج
أضف خاصية birthday قيمتها undefined إلى الكائن، وشاهد هل تظهر في النص. ثم غيّر الاستدعاء إلى JSON.stringify(student, null, 2).
أخطاء شائعة
Section titled “أخطاء شائعة”- محاولة قراءة خاصية من نص JSON:
text.nameتُرجعundefined، لأنtextنص وليس كائناً. استخدمJSON.parseأولاً. - استخدام parse مع كائن:
JSON.parse(user)خطأ، لأنparseتنتظر نصاً. - كتابة JSON بعلامات تنصيص مفردة أو فاصلة أخيرة: يرفضها
parse. JSON أكثر صرامة من JavaScript.
اختبر نفسك
Section titled “اختبر نفسك”سؤال
ما نوع القيمة التي تُرجعها JSON.stringify؟
stringify تحوّل الكائن إلى نص JSON يمكن إرساله أو حفظه، و typeof لها يعطي string.
سؤال
أي نص مما يلي JSON صالح؟
في JSON يجب أن تكون أسماء الخصائص والنصوص بين علامتي تنصيص مزدوجتين.
الخلاصة
Section titled “الخلاصة”- JSON صيغة نصية مشتركة لتبادل البيانات بين كل اللغات.
- قواعدها صارمة: علامات تنصيص مزدوجة، ولا فاصلة أخيرة، ولا تعليقات ولا دوال.
JSON.stringifyتحوّل الكائن إلى نص، وJSON.parseتعيد النص كائناً.- النص غير الصالح يسبب
SyntaxError، فاستخدمtryوcatch. - للنسخ العميق استخدم
structuredClone.