🧩 ما هو الـ Nested Object؟
هو كائن (Object) يحتوي بداخله على كائن آخر كمفتاح (Property).
ببساطة: كأنك تضع كائنًا داخل كائن.
✅ مثال بسيط:
const student = {
name: "Sara",
age: 20,
address: {
city: "Cairo",
country: "Egypt"
}
};
JavaScriptaddress
هو خاصية داخل 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