الكلاس في لغة JavaScript


الكلاس في لغة JavaScript

يا هلا والله! اليوم بنتكلم عن الكلاسات في جافاسكريبت، وكيف تسهل علينا كتابة أكواد منظمة وقابلة لإعادة الاستخدام. جافاسكريبت لغة مبنية على "البروتوتايب" (Prototype-based)، لكن مع ES6، جابوا لنا طريقة نكتب فيها الكلاسات بشكل أقرب للغات الثانية زي جافا و C#، وهذا يخلي الشغل أسهل وأوضح.

1. تعريف الكلاس (Class Definition)

عشان تسوي كلاس، تستخدم الكلمة المفتاحية class وبعدها اسم الكلاس (يفضل يكون بأول حرف كبير - PascalCase). شوف المثال:

ملاحظة: الكلاسات في جافاسكريبت هي مجرد "سكر نحوي" (Syntactic Sugar) فوق دوال البناء (Constructor Functions) والبروتوتايب. يعني هي ما تغير كيف جافاسكريبت تشتغل من تحت، بس تسهل عليك الكتابة والقراءة.

class Car {
  // هنا بتحط خصائص الكلاس والدوال (الميثودز)
}

2. دالة البناء (Constructor Method)

كل كلاس يقدر يكون عنده دالة بناء اسمها constructor. هذي الدالة تتنفذ أول ما تسوي كائن جديد (instance) من الكلاس. تستخدمها عشان تهيئ الخصائص الأولية للكائن.

class Car {
  constructor(brand, model, year) {
    this.brand = brand;
    this.model = model;
    this.year = year;
  }
}

الـ this هنا تشير للكائن اللي قاعدين ننشئه حالياً.

3. إضافة دوال (Methods) للكلاس

الكلاسات مو بس تحمل خصائص، تقدر تحط فيها دوال (ميثودز) تسوي شغلات معينة. الدوال هذي تكون مشتركة بين كل الكائنات اللي تسويها من الكلاس.

class Car {
  constructor(brand, model, year) {
    this.brand = brand;
    this.model = model;
    this.year = year;
  }

  getCarInfo() {
    return <code dir="ltr" style="background:#f3f4f6; color:#0056b3; padding:2px 6px; border-radius:4px; font-family:monospace; direction:ltr !important; display:inline-block;">هذي سيارة من نوع ${this.brand}، موديل ${this.model}، سنة ${this.year}.</code>;
  }

  startEngine() {
    return <code dir="ltr" style="background:#f3f4f6; color:#0056b3; padding:2px 6px; border-radius:4px; font-family:monospace; direction:ltr !important; display:inline-block;">${this.brand} ${this.model} اشتغل محركها!</code>;
  }
}

4. إنشاء كائنات (Instances) من الكلاس

بعد ما عرفت الكلاس، تقدر تسوي منه كائنات (objects) جديدة باستخدام الكلمة المفتاحية new.

const myCar = new Car('Toyota', 'Camry', 2023);
const yourCar = new Car('Honda', 'Civic', 2022);

console.log(myCar.getCarInfo()); // هذي سيارة من نوع Toyota، موديل Camry، سنة 2023.
console.log(yourCar.startEngine()); // Honda Civic اشتغل محركها!

5. الوراثة (Inheritance)

من أقوى مميزات الكلاسات هي الوراثة. تقدر تخلي كلاس "يرث" من كلاس ثاني، وهذا يعني إنه بياخذ كل الخصائص والدوال اللي فيه، وتقدر تضيف عليها أو تعدل فيها. تستخدم extends للوراثة و super عشان تنادي دالة البناء (constructor) أو دوال الكلاس الأب.

class ElectricCar extends Car {
  constructor(brand, model, year, batteryLife) {
    super(brand, model, year); // ننادي دالة البناء للكلاس الأب (Car)
    this.batteryLife = batteryLife;
  }

  charge() {
    return <code dir="ltr" style="background:#f3f4f6; color:#0056b3; padding:2px 6px; border-radius:4px; font-family:monospace; direction:ltr !important; display:inline-block;">${this.brand} ${this.model} قاعدة تشحن بطاريتها، عمر البطارية المتبقي: ${this.batteryLife} ساعة.</code>;
  }

  // نقدر نعدل على دالة من الكلاس الأب (Override)
  startEngine() {
    return <code dir="ltr" style="background:#f3f4f6; color:#0056b3; padding:2px 6px; border-radius:4px; font-family:monospace; direction:ltr !important; display:inline-block;">${this.brand} ${this.model} محركها الكهربائي اشتغل بهدوء!</code>;
  }
}

const tesla = new ElectricCar('Tesla', 'Model 3', 2024, 8);
console.log(tesla.getCarInfo()); // هذي سيارة من نوع Tesla، موديل Model 3، سنة 2024.
console.log(tesla.startEngine()); // Tesla Model 3 محركها الكهربائي اشتغل بهدوء!
console.log(tesla.charge()); // Tesla Model 3 قاعدة تشحن بطاريتها، عمر البطارية المتبقي: 8 ساعة.

6. الدوال الثابتة (Static Methods)

أحياناً تحتاج دوال تكون مرتبطة بالكلاس نفسه، مو بكائن معين منه. يعني ما تحتاج تسوي new عشان تستخدمها. هنا يجي دور الدوال الثابتة static.

class MathHelper {
  static add(a, b) {
    return a + b;
  }

  static multiply(a, b) {
    return a * b;
  }
}

console.log(MathHelper.add(5, 3));      // 8
console.log(MathHelper.multiply(4, 2)); // 8
// ما يحتاج تسوي new MathHelper() عشان تستخدمها

7. الـ Getters والـ Setters

هذي دوال خاصة تسمح لك تتحكم كيف يتم الوصول للخصائص أو تعديلها في الكلاس. تستخدم الكلمتين المفتاحيتين get و set.

class User {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  get fullName() {
    return <code dir="ltr" style="background:#f3f4f6; color:#0056b3; padding:2px 6px; border-radius:4px; font-family:monospace; direction:ltr !important; display:inline-block;">${this.firstName} ${this.lastName}</code>;
  }

  set fullName(value) {
    const parts = value.split(' ');
    this.firstName = parts[0];
    this.lastName = parts[1];
  }
}

const user1 = new User('أحمد', 'المحمد');
console.log(user1.fullName); // أحمد المحمد

user1.fullName = 'سارة العلي';
console.log(user1.firstName); // سارة
console.log(user1.lastName);  // العلي

لاحظ إنك تتعامل مع fullName كأنها خاصية عادية، بس من ورا الكواليس هي دالة get أو set.

8. الخصائص الخاصة (Private Class Fields) - تجريبي

في الإصدارات الحديثة من جافاسكريبت (خاصية تجريبية حالياً)، تقدر تعرف خصائص تكون خاصة بالكلاس وما تقدر توصل لها من برا الكلاس. تستخدم علامة # قبل اسم الخاصية.

class BankAccount {
  #balance; // خاصية خاصة

  constructor(initialBalance) {
    this.#balance = initialBalance;
  }

  deposit(amount) {
    if (amount > 0) {
      this.#balance += amount;
      return <code dir="ltr" style="background:#f3f4f6; color:#0056b3; padding:2px 6px; border-radius:4px; font-family:monospace; direction:ltr !important; display:inline-block;">تم إيداع ${amount}. الرصيد الجديد: ${this.#balance}</code>;
    }
    return 'مبلغ الإيداع يجب أن يكون موجباً.';
  }

  getBalance() {
    return <code dir="ltr" style="background:#f3f4f6; color:#0056b3; padding:2px 6px; border-radius:4px; font-family:monospace; direction:ltr !important; display:inline-block;">الرصيد الحالي: ${this.#balance}</code>;
  }
}

const myAccount = new BankAccount(1000);
console.log(myAccount.deposit(500)); // تم إيداع 500. الرصيد الجديد: 1500
// console.log(myAccount.#balance); // بيعطيك خطأ لأنها خاصية خاصة
console.log(myAccount.getBalance()); // الرصيد الحالي: 1500

ملاحظة: الخصائص الخاصة # هي ميزة جديدة نسبياً وما زالت في مرحلة التجريب (Stage 3 proposal)، تأكد من دعم المتصفحات أو استخدام Babel إذا كنت بتستخدمها في مشروعك.

وبكذا نكون غطينا أساسيات الكلاسات في جافاسكريبت. استخدامها بيخلي كودك أنظف، أسهل للقراءة، وأكثر قابلية للصيانة والتوسع. بالتوفيق في رحلتك البرمجية!