مدخل إلى جافاسكريبت كائنية التوجه (Object-Oriented JavaScript)
تُعدّ جافاسكريبت من اللغات البرمجية الديناميكية القوية التي شهدت تطورًا كبيرًا منذ نشأتها، حيث انتقلت من كونها لغة بسيطة لكتابة سكريبتات ضمن صفحات الويب إلى لغة برمجة متعددة الأوجه تدعم مفاهيم متقدمة مثل البرمجة الكائنية (Object-Oriented Programming – OOP). رغم أن جافاسكريبت ليست لغة كائنية بالمعنى التقليدي مثل جافا أو ++C، إلا أنها توفر دعماً واسعاً للبرمجة الكائنية باستخدام النموذج القائم على النماذج الأولية (Prototype-based). يُعتبر فهم هذه الآلية أمرًا بالغ الأهمية للمطورين الذين يسعون إلى كتابة كود منظم، قابل لإعادة الاستخدام، ويسهل صيانته.
في هذا المقال، سيتم تناول مفهوم البرمجة كائنية التوجه في جافاسكريبت بالتفصيل، مع شرح الأسس النظرية والتطبيقية، وأهم الميزات والاختلافات عن اللغات الكائنية الأخرى، مع أمثلة وشروحات موسعة.
أولاً: المفاهيم الأساسية للبرمجة كائنية التوجه
الكائنات (Objects)
في جوهر البرمجة كائنية التوجه، نجد الكائنات. الكائن هو بنية تحتوي على خصائص (خصائص بيانات تُسمى “الخصائص” أو “properties”) وسلوكيات (وظائف تُسمى “الأساليب” أو “methods”).
في جافاسكريبت، يمكن إنشاء كائن باستخدام الصيغة التالية:
javascriptlet person = {
name: "Ali",
age: 30,
greet: function() {
console.log("Hello, my name is " + this.name);
}
};
النماذج الأولية (Prototypes)
خلافًا للعديد من اللغات الأخرى التي تعتمد على الأصناف (classes)، فإن جافاسكريبت تعتمد على النموذج الأولي كنموذج وراثي. الكائنات في جافاسكريبت يمكنها وراثة الخصائص والأساليب من كائنات أخرى.
كل كائن في جافاسكريبت له خاصية خفية تسمى [[Prototype]]، يمكن الوصول إليها من خلال __proto__ أو باستخدام الدالة Object.getPrototypeOf().
ثانياً: إنشاء كائنات باستخدام الدوال البانية (Constructor Functions)
قبل إدخال الكلمة المفتاحية class في ES6، كانت الطريقة التقليدية لإنشاء كائنات مخصصة هي استخدام دوال البانية.
javascriptfunction Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function() {
console.log("Hi, I'm " + this.name);
};
let person1 = new Person("Ahmed", 25);
person1.greet(); // Hi, I'm Ahmed
التحليل
-
Personهنا دالة بانية (constructor). -
الكلمة المفتاحية
newتُستخدم لإنشاء كائن جديد وربطه بالبروتوتايب الخاص بـPerson. -
خاصية
greetتتم إضافتها إلى النموذج الأولي وليس إلى كل كائن على حدة، ما يوفر استخدامًا أفضل للذاكرة.
ثالثاً: الكائنات والميراث (Inheritance)
جافاسكريبت تدعم الوراثة من خلال البروتوتايب. يمكن لكائن أن يرث من كائن آخر خصائصه وأساليبه.
javascriptfunction Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(this.name + " makes a noise.");
};
function Dog(name) {
Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() {
console.log(this.name + " barks.");
};
let dog1 = new Dog("Rex");
dog1.speak(); // Rex makes a noise.
dog1.bark(); // Rex barks.
آلية الوراثة
-
يتم استدعاء
Animal.call(this, name)داخلDogلتوريث الخصائص. -
يتم ربط النموذج الأولي لـ
DogبنموذجAnimalعبرObject.create.
رابعاً: استخدام الكلمة المفتاحية class في ES6
مع إدخال ES6، أصبحت البرمجة الكائنية في جافاسكريبت أكثر قربًا إلى اللغات الأخرى من حيث الصياغة بفضل الكلمة المفتاحية class.
javascriptclass Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name}`);
}
}
let p = new Person("Youssef", 40);
p.greet(); // Hello, my name is Youssef
الوراثة مع class
javascriptclass Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise`);
}
}
class Dog extends Animal {
bark() {
console.log(`${this.name} barks`);
}
}
let d = new Dog("Max");
d.speak(); // Max makes a noise
d.bark(); // Max barks
الميزات التي توفرها class
-
بناء نحوي أوضح وأسهل للفهم.
-
دعم مباشر للوراثة عبر
extends. -
استخدام
super()للوصول إلى البنية العليا.
خامساً: المفاهيم المتقدمة في البرمجة الكائنية بجافاسكريبت
الكائنات الثابتة والمجمدة
يمكن إنشاء كائنات لا يمكن تعديلها باستخدام Object.freeze().
javascriptconst car = {
brand: "Toyota"
};
Object.freeze(car);
car.brand = "Honda"; // لا يحدث أي تغيير
الخصائص الخاصة (Private Properties)
بدءًا من ES2022، أصبح من الممكن استخدام الخصائص الخاصة باستخدام الحرف #.
javascriptclass Counter {
#count = 0;
increment() {
this.#count++;
console.log(this.#count);
}
}
let c = new Counter();
c.increment(); // 1
// c.#count; => SyntaxError
سادساً: المقارنة بين النموذج القديم والنموذج الحديث (Prototypes vs Classes)
| الخاصية | النماذج الأولية (Prototypes) | الكلاسات (Classes) |
|---|---|---|
| الدعم الأصلي | منذ إنشاء جافاسكريبت | بدءًا من ES6 |
| الشكل البنائي | يعتمد على الدوال | بنية مشابهة لجافا وجميع لغات OOP |
| الوراثة | باستخدام Object.create و call() |
باستخدام extends و super() |
| الوضوح والسهولة | أقل وضوحًا للمبتدئين | أكثر وضوحًا ومرونة |
| قابلية الصيانة | معقدة في المشاريع الكبيرة | أكثر سهولة للتوسع والتنظيم |
سابعاً: فوائد استخدام البرمجة الكائنية في جافاسكريبت
-
إعادة استخدام الكود (Code Reusability): من خلال الوراثة، يمكن إنشاء كائنات جديدة دون الحاجة إلى تكرار الكود.
-
المرونة والتوسع (Flexibility & Scalability): الكائنات يمكن توسيعها لتلبية احتياجات التطبيقات المعقدة.
-
تنظيم الكود: يساعد OOP على تقسيم التطبيق إلى وحدات صغيرة يسهل التعامل معها وصيانتها.
-
تقليل التكرار: باستخدام الوراثة والنماذج الأولية يمكن تجنب التكرار.
-
التفاعل مع مكتبات وأطر العمل: معظم مكتبات جافاسكريبت الحديثة (مثل React, Vue, Angular) تعتمد بشكل كبير على مفاهيم OOP.
ثامناً: التحديات والقيود
رغم المزايا الكبيرة التي توفرها البرمجة الكائنية في جافاسكريبت، إلا أن هناك بعض التحديات التي يجب أخذها بعين الاعتبار:
-
الخلط بين النماذج الأولية والكلاسات: الانتقال من الكود القديم إلى الكود الحديث يتطلب معرفة عميقة بكلا النموذجين.
-
عدم وجود دعم صارم للخصائص الخاصة قبل ES2022: مما يُصعّب إنشاء نماذج آمنة ومغلقة تمامًا.
-
أداء الوراثة العميقة: قد يُسبب تعقيدات خاصة في التطبيقات الكبيرة جدًا.
تاسعاً: أمثلة على تطبيقات تستخدم OOP في جافاسكريبت
-
نظام إدارة مستخدمين:
-
إنشاء كائن
Userيحتوي على خصائص مثل الاسم، البريد الإلكتروني، وكلمة المرور. -
إنشاء كائن
Adminيرث منUserويحتوي على صلاحيات إضافية.
-
-
محرك لعبة:
-
كائن
Characterيحتوي على خصائص مثل الموقع، الصحة، القوة. -
كائنات فرعية مثل
HeroوMonsterترث منCharacter.
-
-
إدارة سلة تسوق:
-
كائن
Productيحتوي على السعر والكمية. -
كائن
Cartيحتوي على قائمة المنتجات ويحسب السعر الإجمالي.
-
عاشراً: الخلاصة التقنية
البرمجة كائنية التوجه في جافاسكريبت ليست مجرد خيار، بل أصبحت أداة ضرورية لتطوير التطبيقات الحديثة بطريقة منظمة ومستدامة. سواء باستخدام النماذج الأولية أو الكلاسات، توفر جافاسكريبت طرقًا مرنة لتصميم البرامج وفقًا لمبادئ OOP. الفهم العميق لهذه الآليات يُمكّن المطور من تحسين جودة الكود، وزيادة قابليته لإعادة الاستخدام، وتقليل تعقيدات الصيانة مع تطور حجم المشروع.
المراجع:
-
David Flanagan, JavaScript: The Definitive Guide, O’Reilly Media.
-
Mozilla Developer Network (MDN): https://developer.mozilla.org/en-US/docs/Web/JavaScript

