Skip to content

13. الفئات

Image

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

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

يوضح البرنامج النصي التالي استخدامًا غير معتاد للدوال. هنا، يتم استخدامها ككائنات.


'use strict';
// a function can be used as an object
 
// an empty shell
function f() {
 
}
// to which external properties are attributed
f.prop1 = "val1";
f.show = function () {
  console.log(this.prop1);
}
// use of f
f.show();
 
// a function g operating as a class
function g() {
  this.prop2 = "val2";
  this.show = function () {
    console.log(this.prop2);
  }
}
// instantiate the function with [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] فئة [Person]:


// class
class Personne {
 
  // manufacturer
  constructor(nom, prénom, âge) {
    this.nom = nom;
    this.prénom = prénom;
    this.âge = âge;
  }
 
  // getters and setters
  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 to JSON
  toString() {
    return JSON.stringify(this);
  }
}
 
// class call
function main() {
  const personne = new Personne("Poirot", "Hercule", 66);
  console.log("personne=", personne.toString(), typeof (personne), personne instanceof (Personne));
}
 
// hand call
main();

تعليقات

  • السطر 2: تشير الكلمة الرئيسية [class] إلى فئة؛
  • الأسطر 5–9: تشير الكلمة الرئيسية [constructor] إلى مُنشئ الفئة. يمكن أن يكون هناك واحد على الأكثر. ويُستخدم لإنشاء وتهيئة مثيل للفئة. لاحظ أنه لا يوجد إعلان للخصائص [last_name, first_name, age]؛
  • الأسطر 11–36: خصائص الفئة. نرى هنا عناصر تمت تغطيتها بالفعل في القسم الخاص بالكائنات 4، الصفحة 44. يختلف فقط بناء الجملة؛
  • السطر 41: إنشاء كائن من النوع [Person]. من الآن فصاعدًا، يُستخدم الكائن [person] ككائن حرفي. يُقيَّم [typeof (person)] إلى «object» ويكون التعبير [person instanceof (Person)] صحيحًا. لذلك، من الممكن تحديد النوع الدقيق لمثيل الفئة؛

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


[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].

أولاً، ننقل فئة [Person] إلى وحدة نمطية تسمى [Person.js]:


// classe
class Personne {
 
  // constructeur
  constructor(nom, prénom, âge) {
    this.nom = nom;
    this.prénom = prénom;
    this.âge = âge;
  }
 
  // getters et setters
  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 en JSON
  toString() {
    return JSON.stringify(this);
  }
}
// export classe
export default Personne;
  • السطر 39: نقوم بتصدير فئة [Person] حتى تتمكن البرامج النصية من استيرادها؛

ينشئ البرنامج النصي [class-02] فئة [Teacher] مشتقة من فئة [Person]:


// imports
import Personne from './Personne';
 
// classe
class Enseignant extends Personne {
 
  // constructeur
  constructor(nom, prénom, âge, discipline) {
    super(nom, prénom, âge);
    this.discipline = discipline;
  }
 
  // getters et setters
  get discipline() {
    return this._discipline;
  }
  set discipline(value) {
    this._discipline = value;
  }
 
}
 
// appel de la classe
function main() {
  const enseignant = new Enseignant("Poirot", "Hercule", 66, "détective");
  console.log("enseignant=", enseignant.toString(), typeof (enseignant), enseignant instanceof Enseignant);
}
 
// appel de main
main();

تعليقات

  • السطر 2: نستورد فئة [Person] من الوحدة النمطية [Person.js]، الموجودة في نفس المجلد الذي توجد فيه [class-02]؛
  • السطر 5: تمتد فئة [Teacher] (ترث) من فئة [Person] باستخدام الكلمة الرئيسية [extends]: تضيف خاصية [_subject] مع طرق getter و setter المقابلة؛
  • الأسطر 8–11: يتلقى منشئ فئة [Teacher] أربع قيم لتهيئة الخصائص الأربع للفئة؛
  • السطر 9: تستدعي الكلمة الرئيسية [super] منشئ الفئة الأم [Personوالتي ستقوم بالتالي بتهيئة الخصائص [_last_name، _first_name، _age]؛
  • السطر 10: يتم تهيئة الخاصية [_discipline] التابعة لفئة [Teacher]؛
  • الأسطر 14-19: طرق الحصول والتعيين للخاصية [_discipline]؛
  • السطر 25: يتم إنشاء كائن من النوع [Teacher]؛
  • السطر 26: نستخدم الطريقة [teacher.toString()]. لا تحتوي فئة [Teacher] على هذه الطريقة. لذلك، يتم استخدام الطريقة من فئتها الأم تلقائيًا. تعرض هذه الطريقة التعبير [JSON.stringify(this)]، حيث سيكون [this] كائنًا من نوع [Teacher] هنا، وليس كائنًا من نوع [Person]. هذا ما يُعرف في البرمجة الموجهة للكائنات باسم تعدد أشكال الفئة. مصطلح كبير بالنسبة لـ 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: يتعرف JavaScript بشكل صحيح على أن المتغير [teacher] هو من النوع [Teacher]؛

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

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


// imports
import Personne from './Personne';
 
// classe
class Enseignant extends Personne {
 
  // constructeur
  constructor(nom, prénom, âge, discipline) {
    super(nom, prénom, âge);
    this.discipline = discipline;
  }
 
  // getters et setters
  get discipline() {
    return this._discipline;
  }
  set discipline(value) {
    this._discipline = value;
  }
 
  // redéfinition de toString
  toString() {
    return "[Enseignant]" + JSON.stringify(this);
  }
}
 
// appel de la classe
function main() {
  const enseignant = new Enseignant("Poirot", "Hercule", 66, "détective");
  console.log("enseignant=", enseignant.toString(), typeof (enseignant), enseignant instanceof Enseignant);
}
 
// appel de 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. script [class-04]

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

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


// imports
import Personne from './Personne';
 
// classe
class Enseignant extends Personne {
 
  // constructeur
  constructor(nom, prénom, âge, discipline) {
    super(nom, prénom, âge);
    this.discipline = discipline;
  }
 
  // getters et setters
  get discipline() {
    return this._discipline;
  }
  set discipline(value) {
    this._discipline = value;
  }
 
}
 
// export classe
export default Enseignant;
  • السطر 24: يتم تصدير فئة [Teacher] حتى تتمكن البرامج النصية الأخرى من استيرادها؛

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


// imports
import Enseignant from './Enseignant';
import Personne from './Personne';
 
// fonction acceptant une personne comme paramètre
function show(personne) {
  // dans tous les cas
  console.log("paramètre=", personne.toString(), typeof (personne));
  // instance de Personne
  if (personne instanceof Personne) {
    console.log("personne=", personne.toString());
  }
  // instance de Enseignant
  if (personne instanceof Enseignant) {
    console.log("enseignant=", personne.toString());
  }
}
 
// appel de show avec un enseignant
show(new Enseignant("Poirot", "Hercule", 66, "détective"));
show(new Personne("Marple", "Miss", 70));
  • السطر 6: تتوقع الدالة [show] نوع [Person] أو نوعًا مشتقًا منه؛
  • السطر 8: يتم عرض سلسلة المعلمة ونوعها. سنجد [object]؛
  • الأسطر 10-16: يمكننا تحديد ما إذا كان نوع [Person] أو نوع [Teacher]. وبالتالي يمكن تكييف الكود مع النوع الفعلي للمعلمة؛

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


[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: يتعرف JavaScript بشكل صحيح على نوع مثيلات الفئة؛