Nested Object

🧩 ما هو الـ Nested Object؟

هو كائن (Object) يحتوي بداخله على كائن آخر كمفتاح (Property).
ببساطة: كأنك تضع كائنًا داخل كائن.

✅ مثال بسيط:

const student = {
  name: "Sara",
  age: 20,
  address: {
    city: "Cairo",
    country: "Egypt"
  }
};
JavaScript

address هو خاصية داخل student.

وقيمته كائن آخر يحتوي على city و country.

🧭 كيفية الوصول إلى البيانات المتداخلة؟
1. باستخدام Dot Notation:
console.log(student.address.city);      // "Cairo"
console.log(student.address.country);   // "Egypt"
JavaScript

باستخدام Bracket Notation:

console.log(student["address"]["city"]);    // "Cairo"
JavaScript
🔁 التعديل على كائن متداخل:
student.address.city = "Alexandria";
console.log(student.address.city); // "Alexandria"
JavaScript

➕ إضافة خاصية جديدة داخل كائن متداخل:

student.address.zip = "12345";
console.log(student.address.zip); // "12345"
JavaScript

🧹 حذف خاصية متداخلة:

delete student.address.country;
console.log(student.address.country); // undefined
JavaScript

🧠 كائن متداخل داخل مصفوفة (شائع جدًا):

const school = {
  name: "Future School",
  students: [
    { name: "Ali", grade: "A" },
    { name: "Laila", grade: "B" }
  ]
};

console.log(school.students[0].name); // "Ali"
console.log(school.students[1].grade); // "B"
JavaScript

💡 مثال عملي متقدم:

const company = {
  name: "TechSoft",
  departments: {
    development: {
      teamLead: "Ahmed",
      developers: ["Omar", "Yara"]
    },
    marketing: {
      teamLead: "Mona",
      tools: ["SEO", "Email"]
    }
  }
};

console.log(company.departments.development.teamLead); // "Ahmed"
console.log(company.departments.marketing.tools[1]);   // "Email"
JavaScript

📌 تمرين سريع:

أعطيتك الكائن التالي:

const user = {
  id: 101,
  profile: {
    username: "coder123",
    contact: {
      email: "[email protected]",
      phone: "123456"
    }
  }
};
JavaScript

الكائنات المتداخلة (Nested Objects) تعتبر من أهم مفاهيم JavaScript، وهناك بالفعل نقاط متقدمة ومهمة يجب معرفتها بعد الفهم الأساسي، وسأشرحها لك الآن بشكل مبسط:

✅ 1. التحقق من وجود قيم داخل كائن متداخل (قبل الوصول)

إذا حاولت الوصول إلى خاصية متداخلة غير موجودة مباشرة، قد تحصل على خطأ.

❌ خطأ محتمل:
console.log(user.profile.contact.email); 
// لو profile أو contact غير موجود → TypeError
JavaScript

✅ الحل باستخدام optional chaining (علامة ?.):

console.log(user?.profile?.contact?.email); 
// إذا أي خاصية غير موجودة → يرجّع undefined بدل الخطأ
JavaScript

مفيد جدًا خاصة عند التعامل مع بيانات من API أو JSON خارجي.

✅ 2. الوصول إلى خصائص داخل حلقات

مثلاً إذا كان لديك مصفوفة كائنات، كل كائن يحتوي على كائن متداخل:

const users = [
  { id: 1, info: { name: "Ali", city: "Cairo" } },
  { id: 2, info: { name: "Sara", city: "Alex" } }
];

users.forEach(user => {
  console.log(user.info.name + " from " + user.info.city);
});
JavaScript
✅ 3. النسخ العميق (Deep Copy) مقابل النسخ السطحي (Shallow Copy)

لو حاولت نسخ كائن متداخل باستخدام spread أو Object.assign()، سيتم نسخ المرجع فقط للكائنات المتداخلة، وليس القيم نفسها.

❌ خطأ شائع:
const original = { user: { name: "Ali" } };
const copy = { ...original };

copy.user.name = "Omar";

console.log(original.user.name); // 😱 "Omar" ← تغيّر الأصل!
JavaScript

✅ حل النسخ العميق:

const deepCopy = JSON.parse(JSON.stringify(original));
JavaScript

هذه الطريقة بسيطة لكنها لا تدعم الكائنات التي تحتوي على دوال أو تواريخ.

✅ 4. تعديل خصائص كائنات متداخلة داخل دوال

إذا كنت تعمل داخل دالة وتحتاج تعديل كائن متداخل، تذكر أن الكائنات تمر بالمرجع (by reference)، لذا سيتم تعديل الأصل مباشرة:

function updateName(userObj) {
  userObj.profile.name = "New Name";
}

updateName(user); // ← يغيّر قيمة user الأصلي!
JavaScript
✅ 5. تحويل كائن متداخل إلى مصفوفة

أحيانًا تحتاج لتحويل الكائن إلى مصفوفة لأغراض العرض أو التكرار:

const user = {
  name: "Ali",
  contact: {
    email: "[email protected]",
    phone: "1234"
  }
};

const contactArray = Object.entries(user.contact);
/*
[
  ["email", "[email protected]"],
  ["phone", "1234"]
]
*/
JavaScript
✅ 6. دمج كائنات متداخلة

باستخدام spread operator:

const a = { settings: { theme: "dark" } };
const b = { settings: { layout: "grid" } };

// الدمج العادي لا يفيد!
const merged = { ...a, ...b }; 
// settings → فقط من b

// تستخدم مكتبات مثل lodash أو deep merge لحل هذه المشكلة
JavaScript