13. الفئات

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