الكائنات في لغة JavaScript


الكائنات في لغة JavaScript

يا هلا بالشباب! اليوم بنتكلم عن الكائنات (Objects) في JavaScript. بصراحة، الكائنات هي العمود الفقري لأي شي تسويه في الجافاسكريبت. كل شي تقريباً في جافاسكريبت هو كائن، من المصفوفات للدوال وحتى الـ null والـ undefined لهم سلوكيات تشبه الكائنات في بعض الأحيان.

وش يعني كائن؟

الكائن هو مجرد مجموعة من البيانات والوظائف المرتبطة ببعضها. تخيل عندك سيارة، السيارة هذي لها خصائص (لون، موديل، سنة الصنع) ولها أفعال تسويها (تشغيل، إيقاف، قيادة). في عالم البرمجة، الخصائص نسميها "Properties" والأفعال نسميها "Methods".

ملاحظة: الكائنات في JavaScript هي من نوع "key-value pairs" يعني لكل خاصية اسم (مفتاح) وقيمة مرتبطة بها.

كيف نسوي كائن؟

أسهل طريقة هي باستخدام الأقواس المعقوفة {} وهذا يسموه "Object Literal":


const سيارة = {
  اللون: "أحمر",
  الموديل: "كامري",
  سنة_الصنع: 2023,
  تشغيل: function() {
    console.log("السيارة اشتغلت!");
  },
  إيقاف() { // طريقة مختصرة لتعريف الدوال
    console.log("السيارة طفت.");
  }
};

تقدر تسوي كائن فاضي بعدين تضيف عليه الخصائص:


const شخص = {};
شخص.الاسم = "أحمد";
شخص.العمر = 30;
شخص.المدينة = "الرياض";

كيف نوصل لخصائص الكائن؟

فيه طريقتين: "Dot Notation" (النقطة) و "Bracket Notation" (الأقواس المربعة).

Dot Notation (الطريقة الشائعة):


console.log(سيارة.اللون); // أحمر
سيارة.سنة_الصنع = 2024; // تغيير قيمة
console.log(سيارة.سنة_الصنع); // 2024

Bracket Notation (لما يكون اسم الخاصية فيه مسافة أو جاي من متغير):


console.log(سيارة["الموديل"]); // كامري

const مفتاح_خاصية = "اللون";
console.log(سيارة[مفتاح_خاصية]); // أحمر

ملاحظة: إذا حاولت توصل لخاصية مو موجودة، بيعطيك undefined.

الدوال داخل الكائنات (Methods)

الدوال اللي داخل الكائنات نسميها "Methods". عشان تستدعيها، تستخدم نفس طريقة الوصول للخصائص:


سيارة.تشغيل(); // السيارة اشتغلت!
سيارة.إيقاف(); // السيارة طفت.

كلمة this

داخل الـ "Method" ممكن تحتاج توصل لخصائص الكائن نفسه. هنا يجي دور كلمة this.


const منتج = {
  الاسم: "لابتوب",
  السعر: 5000,
  عرض_التفاصيل: function() {
    console.log(اسم المنتج: ${this.الاسم}, السعر: ${this.السعر} ريال.);
  }
};

منتج.عرض_التفاصيل(); // اسم المنتج: لابتوب, السعر: 5000 ريال.

ملاحظة مهمة: قيمة this تتغير حسب سياق الاستدعاء. هذي نقطة يبيلها درس لحالها، بس اعرف إنها داخل دوال الكائنات (Methods) تشير للكائن نفسه.

التكرار على الكائنات (Iterating Objects)

إذا بغيت تمر على كل خصائص الكائن، تقدر تستخدم for...in:


for (let مفتاح in سيارة) {
  if (typeof سيارة[مفتاح] !== 'function') { // نتجاهل الدوال
    console.log(${مفتاح}: ${سيارة[مفتاح]});
  }
}
// اللون: أحمر
// الموديل: كامري
// سنة_الصنع: 2024

أو تستخدم دوال Object المدمجة:


console.log(Object.keys(سيارة));   // [ 'اللون', 'الموديل', 'سنة_الصنع', 'تشغيل', 'إيقاف' ]
console.log(Object.values(سيارة)); // [ 'أحمر', 'كامري', 2024, [Function: تشغيل], [Function: إيقاف] ]
console.log(Object.entries(سيارة)); // [ [ 'اللون', 'أحمر' ], [ 'الموديل', 'كامري' ], ... ]

نسخ الكائنات (Object Copying)

لما تنسخ كائن بشكل مباشر، أنت فعلياً تنسخ "المرجع" حقه، مو الكائن نفسه. يعني لو غيرت شي في النسخة، بيتغير في الأصل والعكس.


const كائن_أصلي = { a: 1, b: 2 };
const كائن_نسخة_مرجعية = كائن_أصلي; // نسخ مرجعي

كائن_نسخة_مرجعية.a = 10;
console.log(كائن_أصلي.a); // 10 (تغير الأصل!)

عشان تسوي نسخة حقيقية (Shallow Copy)، تستخدم Object.assign() أو Spread Syntax ...:


const كائن_أصلي_2 = { x: 1, y: 2 };
const كائن_نسخة_حقيقية_1 = Object.assign({}, كائن_أصلي_2);
const كائن_نسخة_حقيقية_2 = { ...كائن_أصلي_2 }; // Spread Syntax

كائن_نسخة_حقيقية_1.x = 100;
console.log(كائن_أصلي_2.x); // 1 (الأصل ما تغير)

خاتمة

هذا كان ملخص سريع عن الكائنات في JavaScript. الموضوع كبير وفيه تفاصيل أكثر، بس هذي الأساسيات اللي بتخليك تبدأ وتفهم كيف تشتغل الكائنات. طبق الأمثلة هذي عشان تثبت المعلومة وبالتوفيق!