Skip to content

13. الفئات

Image

نقدم هنا فئات ECMAScript 6. أولاً، نوضح أن الدوال يمكن استخدامها بالفعل كفئات.

13.1. نص برمجي [class-00]

يُظهر البرنامج النصي التالي استخدامًا غير معتاد للوظائف. نستخدمها هنا ككائنات.


'use strict';
// يمكن استخدام الدالة ككائن

// قشرة فارغة
function f() {

}
// يتم تعيين خصائص لها من الخارج
f.prop1 = "val1";
f.show = function () {
  console.log(this.prop1);
}
// استخدام f
f.show();

// دالة g تعمل كفئة
function g() {
  this.prop2 = "val2";
  this.show = function () {
    console.log(this.prop2);
  }
}
// إنشاء مثيل للدالة باستخدام [new]
new g().show();

تعليقات

  • الأسطر 5-7: لا يحدد جسم الدالة f أي خاصية؛
  • الأسطر 9-12: يتم إعطاء خصائص للدالة f من الخارج؛
  • السطر 14: استخدام الدالة (الكائن) f. لاحظ أنه لا يتم كتابة [f()] بل ببساطة [f]. هذه هي صيغة الكائن؛
  • الأسطر 17-22: يتم تعريف دالة [g] كما لو كانت فئة ذات خصائص وأساليب؛
  • السطر 24: يتم إنشاء مثيل للدالة [g] بواسطة [new g()]؛

نتائج التنفيذ


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-00.js"
val1
val2

أدخلت ES6 مفهوم الفئة الذي يسمح لنا الآن بتجنب المرور عبر الدوال للحصول على فئات.

13.2. نص برمجي [class-01]

يقدم البرنامج النصي [class-01] فئة [Personne]:


// فئة
class Personne {

  // منشئ
  constructor(nom, prénom, âge) {
    this.nom = nom;
    this.prénom = prénom;
    this.âge = âge;
  }

  // مُستردات ومُعيّنات
  get nom() {
    return this._nom;
  }
  set nom(value) {
    this._nom = value;
  }

  get prénom() {
    return this._prénom;
  }
  set prénom(value) {
    this._prénom = value;
  }

  get âge() {
    return this._âge;
  }
  set âge(value) {
    this._âge = value;
  }

  // toString في JSON
  toString() {
    return JSON.stringify(this);
  }
}

// استدعاء الفئة
function main() {
  const personne = new Personne("Poirot", "Hercule", 66);
  console.log("personne=", personne.toString(), typeof (personne), personne instanceof (Personne));
}

// استدعاء main
main();

تعليقات

  • السطر 2: تشير الكلمة الرئيسية [class] إلى فئة؛
  • الأسطر 5-9: تشير الكلمة الرئيسية [constructor] إلى منشئ الفئة. لا يمكن أن يكون هناك سوى واحد على الأكثر. ويستخدم لإنشاء وتهيئة مثيل للفئة. لاحظ أنه لا يوجد إعلان للخصائص [nom, prénom, âge]؛
  • الأسطر 11-36: خصائص الفئة. نجد هنا أشياء سبق أن رأيناها في الفقرة الخاصة بالكائنات 4، صفحة 44. يختلف فقط بناء الجملة؛
  • السطر 41: إنشاء كائن من النوع [Personne]. من الآن فصاعدًا، يُستخدم الكائن [personne] ككائن حرفي. [typeof (personne)] يساوي "object" والتعبير [personne instanceof (Personne)] صحيح. لذلك، من الممكن معرفة النوع الدقيق لمثيل الفئة؛

نتائج التنفيذ


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-01.js"
personne= {"_nom":"Poirot","_prénom":"Hercule","_âge":66} object true

13.3. نص برمجي [class-02]

يُظهر هذا البرنامج النصي إمكانية وراثة فئة باستخدام الكلمة الرئيسية [extends].

أولاً، نقوم بعزل الفئة [Personne] في وحدة نمطية [Personne.js]:


// الفئة
class Personne {

  // منشئ
  constructor(nom, prénom, âge) {
    this.nom = nom;
    this.prénom = prénom;
    this.âge = âge;
  }

  // مُستردات ومُعيّنات
  get nom() {
    return this._nom;
  }
  set nom(value) {
    this._nom = value;
  }

  get prénom() {
    return this._prénom;
  }
  set prénom(value) {
    this._prénom = value;
  }

  get âge() {
    return this._âge;
  }
  set âge(value) {
    this._âge = value;
  }

  // toString في JSON
  toString() {
    return JSON.stringify(this);
  }
}
// تصدير الفئة
export default Personne;
  • السطر 39: نقوم بتصدير الفئة [Personne] حتى تتمكن البرامج النصية من استيرادها؛

يقوم البرنامج النصي [class-02] بإنشاء فئة [Enseignant] مشتقة من الفئة [Personne]:


// استيرادات
import Personne from './Personne';

// فئة
class Enseignant extends Personne {

  // منشئ
  constructor(nom, prénom, âge, discipline) {
    super(nom, prénom, âge);
    this.discipline = discipline;
  }

  // المُستردات والمُعيّنات
  get discipline() {
    return this._discipline;
  }
  set discipline(value) {
    this._discipline = value;
  }

}

// استدعاء الفئة
function main() {
  const enseignant = new Enseignant("Poirot", "Hercule", 66, "détective");
  console.log("enseignant=", enseignant.toString(), typeof (enseignant), enseignant instanceof Enseignant);
}

// استدعاء main
main();

تعليقات

  • السطر 2: يتم استيراد الفئة [Personne] من الوحدة النمطية [Personne.js] الموجودة في نفس المجلد الذي توجد فيه [class-02]؛
  • السطر 5: الفئة [Enseignant] توسع (ترث) الفئة [Personne] باستخدام الكلمة الرئيسية [extends]: تضيف إليها خاصية [_discipline] مع getter / setter المرتبطة بها؛
  • الأسطر 8-11: يتلقى منشئ الفئة [Enseignant] أربع قيم لتهيئة الخصائص الأربع للفئة؛
  • السطر 9: تستدعي الكلمة الرئيسية [super] منشئ الفئة الأم [Personne] الذي سيقوم بالتالي بتهيئة الخصائص [_nom, _prénom, _âge]؛
  • السطر 10: يتم تهيئة الخاصية [_discipline] التي تنتمي إلى الفئة [Enseignant]؛
  • الأسطر 14-19: دالة getter و dالة setter للخاصية [_discipline]؛
  • السطر 25: يتم إنشاء كائن من النوع [Enseignant]؛
  • السطر 26: يتم استخدام الطريقة [enseignant.toString()]. لا تحتوي الفئة [Enseignant] على هذه الطريقة. لذلك يتم استخدام طريقة الفئة الأم تلقائيًا. هذه الطريقة تجعل التعبير [JSON.stringify(this)] حيث [this] سيكون هنا كائنًا [Enseignant] وليس كائنًا [Personne]. وهذا ما يُسمى في البرمجة الكائنية بتعدد أشكال الفئات. وهو مصطلح كبير بالنسبة لـ Javascript التي ليست لغة موجهة للكائنات. ومع ذلك، فإن Javascript تقوم هنا بما يُتوقع منها: فهي تعرض بالفعل معلمًا؛

نتائج التنفيذ هي كما يلي:


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-02.js"
enseignant= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"} object true
  • السطر 2: يتعرف جافا سكريبت بشكل صحيح على أن المتغير [enseignant] هو من النوع [Enseignant]؛

13.4. نص برمجي [class-03]

يُظهر البرنامج النصي [class-03] أن الفئة الفرعية يمكنها إعادة تعريف خصائص وأساليب الفئة الأصلية. هنا، نعيد تعريف الأسلوب [toString] للفئة الأصلية:


// الاستيرادات
import Personne from './Personne';

// الفئة
class Enseignant extends Personne {

  // المنشئ
  constructor(nom, prénom, âge, discipline) {
    super(nom, prénom, âge);
    this.discipline = discipline;
  }

  // مُستردات ومُعيّنات
  get discipline() {
    return this._discipline;
  }
  set discipline(value) {
    this._discipline = value;
  }

  // إعادة تعريف toString
  toString() {
    return "[Enseignant]" + JSON.stringify(this);
  }
}

// استدعاء الفئة
function main() {
  const enseignant = new Enseignant("Poirot", "Hercule", 66, "détective");
  console.log("enseignant=", enseignant.toString(), typeof (enseignant), enseignant instanceof Enseignant);
}

// استدعاء main
main();

نتائج التنفيذ هي كما يلي:


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-03.js"
enseignant= [Enseignant]{"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"} object true

13.5. نص برمجي [class-04]

يُظهر البرنامج النصي [class-04] مرة أخرى تعدد الأشكال في العمل: حيثما تتوقع دالة معلمة شكلية من النوع [Personne]، يمكن تمرير نوع مشتق مثل [Enseignant]. في الواقع، وبفضل الاشتقاق، يمتلك النوع [Enseignant] جميع سمات النوع [Personne].

أولاً، نقوم بعزل النوع [Enseignant] في وحدة نمطية [Enseignant.js]:


// الاستيرادات
import Personne from './Personne';

// فئة
class Enseignant extends Personne {

  // منشئ
  constructor(nom, prénom, âge, discipline) {
    super(nom, prénom, âge);
    this.discipline = discipline;
  }

  // مُستردات ومُعيّنات
  get discipline() {
    return this._discipline;
  }
  set discipline(value) {
    this._discipline = value;
  }

}

// تصدير الفئة
export default Enseignant;
  • السطر 24: يتم تصدير الفئة [Enseignant] حتى تتمكن البرامج النصية الأخرى من استيرادها؛

النص البرمجي [class-04] هو التالي:


// استيرادات
import Enseignant from './Enseignant';
import Personne from './Personne';

// وظيفة تقبل شخصًا كمعلمة
function show(personne) {
  // في جميع الحالات
  console.log("paramètre=", personne.toString(), typeof (personne));
  // مثيل Personne
  if (personne instanceof Personne) {
    console.log("personne=", personne.toString());
  }
  // مثيل لـ المعلم
  if (personne instanceof Enseignant) {
    console.log("enseignant=", personne.toString());
  }
}

// استدعاء show مع معلم
show(new Enseignant("Poirot", "Hercule", 66, "détective"));
show(new Personne("Marple", "Miss", 70));
  • السطر 6: تنتظر الدالة [show] نوعًا [Personne] أو مشتقًا منه؛
  • السطر 8: يتم عرض سلسلة المعلمة ونوعها. سنجد [object
  • الأسطر 10-16: يمكننا معرفة ما إذا كان النوع هو [Personne] أم [Enseignant]. وبالتالي، يمكن تكييف الكود مع النوع الفعلي للمعلمة؛

نتائج التنفيذ هي كما يلي:


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-04.js"
paramètre= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"} object
personne= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"}
enseignant= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"}
paramètre= {"_nom":"Marple","_prénom":"Miss","_âge":70} object
personne= {"_nom":"Marple","_prénom":"Miss","_âge":70}
  • السطران 4 و6: يتعرف جافا سكريبت بشكل صحيح على نوع مثيلات الفئة؛