Kodax

البرمجة الكائنية (OOP) — JavaScript الأساسيات

البرمجة الكائنية في JavaScript

Classes

class Person {
  // خصائص خاصة (ES2022)
  #id;
  
  // Constructor
  constructor(name, age) {
    this.name = name;
    this.age = age;
    this.#id = Math.random();
  }
  
  // Method
  introduce() {
    return `أنا ${this.name} وعمري ${this.age}`;
  }
  
  // Getter
  get info() {
    return `${this.name} (${this.age})`;
  }
  
  // Setter
  set info(value) {
    [this.name, this.age] = value.split(',');
  }
  
  // Static Method
  static create(name, age) {
    return new Person(name, age);
  }
  
  // Private Method
  #generateId() {
    return Math.random().toString(36);
  }
}

const person = new Person("أحمد", 25);
console.log(person.introduce());
console.log(person.info);

الوراثة (Inheritance)

class Animal {
  constructor(name) {
    this.name = name;
  }
  
  speak() {
    console.log(`${this.name} يصدر صوتاً`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // استدعاء constructor الأب
    this.breed = breed;
  }
  
  speak() {
    console.log(`${this.name} ينبح: هاو هاو!`);
  }
  
  fetch() {
    console.log(`${this.name} يجلب الكرة`);
  }
}

class Cat extends Animal {
  speak() {
    super.speak(); // استدعاء method الأب
    console.log(`${this.name} يموء: مياو!`);
  }
}

const dog = new Dog("ريكس", "جيرمان شيبرد");
dog.speak(); // ريكس ينبح: هاو هاو!

Mixins (التركيب)

class Animal {
  constructor(name) { this.name = name; }
}

// Mixin للقدرات المشتركة
const Flyable = {
  fly() {
    console.log(`${this.name} يطير!`);
  }
};

const Swimmable = {
  swim() {
    console.log(`${this.name} يسبح!`);
  }
};

class Duck extends Animal {
  constructor(name) {
    super(name);
    Object.assign(this, Flyable, Swimmable);
  }
}

const duck = new Duck("دونالد");
duck.fly();  // دونالد يطير!
duck.swim(); // دونالد يسبح!

Design Patterns

Singleton

class Database {
  static #instance;
  
  constructor() {
    if (Database.#instance) {
      return Database.#instance;
    }
    Database.#instance = this;
    this.connection = "connected";
  }
  
  static getInstance() {
    if (!Database.#instance) {
      Database.#instance = new Database();
    }
    return Database.#instance;
  }
}

const db1 = Database.getInstance();
const db2 = Database.getInstance();
console.log(db1 === db2); // true

Factory

class User { constructor(data) { this.name = data.name; this.role = 'user'; } }
class Admin extends User { constructor(data) { super(data); this.role = 'admin'; } }
class Editor extends User { constructor(data) { super(data); this.role = 'editor'; } }

class UserFactory {
  static create(type, data) {
    switch (type) {
      case 'admin':
        return new Admin(data);
      case 'editor':
        return new Editor(data);
      default:
        return new User(data);
    }
  }
}

const admin = UserFactory.create('admin', { name: 'أحمد' });

Observer

class EventEmitter {
  constructor() {
    this.events = {};
  }
  
  on(event, callback) {
    if (!this.events[event]) {
      this.events[event] = [];
    }
    this.events[event].push(callback);
  }
  
  emit(event, data) {
    if (this.events[event]) {
      this.events[event].forEach(callback => callback(data));
    }
  }
  
  off(event, callback) {
    if (this.events[event]) {
      this.events[event] = this.events[event]
        .filter(cb => cb !== callback);
    }
  }
}

const emitter = new EventEmitter();
emitter.on('message', data => console.log('استلمت:', data));
emitter.emit('message', 'مرحباً!');

Module Pattern

const Counter = (function() {
  let count = 0; // private
  
  return {
    increment() { return ++count; },
    decrement() { return --count; },
    getCount() { return count; }
  };
})();

Counter.increment();
Counter.increment();
console.log(Counter.getCount()); // 2
console.log(Counter.count);      // undefined
// Class مع وراثة
class Vehicle {
  constructor(brand, model) {
    this.brand = brand;
    this.model = model;
  }
  
  getInfo() {
    return `${this.brand} ${this.model}`;
  }
}

class Car extends Vehicle {
  constructor(brand, model, doors) {
    super(brand, model);
    this.doors = doors;
  }
  
  getInfo() {
    return `${super.getInfo()} - ${this.doors} أبواب`;
  }
}

const car = new Car("تويوتا", "كامري", 4);
console.log(car.getInfo());

// Observer Pattern
class Subject {
  constructor() {
    this.observers = [];
  }
  
  subscribe(fn) {
    this.observers.push(fn);
  }
  
  notify(data) {
    this.observers.forEach(fn => fn(data));
  }
}

const news = new Subject();
news.subscribe(article => console.log("خبر جديد:", article));
news.notify("تحديث مهم!");
اختبر فهمك