5. الكائنات الحرفية
نسمي هنا "الكائنات الحرفية" الكائنات المحددة حرفياً في الكود. لدى جافا سكريبت مفهوم الفئة، ومفهوم كائن مثيل الفئة. لذا، فإن هذا النوع من الكائنات ليس ما نتحدث عنه الآن.

5.1. script [obj-01]
نقدم هنا الخصائص الأولى للكائنات الحرفية. أهمها أن الكائن يتم التعامل معه عبر مؤشر.
'use strict';
// كائن فارغ
const obj1={};
// يمكن إنشاء خصائص الكائن ديناميكيًا
obj1.prop1="abcd";
console.log('obj1=',obj1);
// خاصية أخرى
obj1.prop2=[1,2,3];
console.log("obj1=",obj1);
// خاصية أخرى بترميز مختلف
obj1['prop3']=true;
console.log("obj1=",obj1);
// obj1 هو مرجع إلى الكائن (مؤشر)، وليس الكائن نفسه
const obj2=obj1;
// obj2 و obj1 يشيران إلى نفس الكائن
obj2.prop1="xyzt";
console.log("obj1=",obj1);
console.log("obj2=",obj2);
// يمكن أن تكون الخصائص متغيرات
const var1='prop1';
console.log('prop1=',obj1[var1]);
التنفيذ
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\objets\obj-01.js"
obj1=[object Object]
obj1= { prop1: 'abcd', prop2: [ 1, 2, 3 ] }
obj1= { prop1: 'abcd', prop2: [ 1, 2, 3 ], prop3: true }
obj1= { prop1: 'xyzt', prop2: [ 1, 2, 3 ], prop3: true }
obj2= { prop1: 'xyzt', prop2: [ 1, 2, 3 ], prop3: true }
prop1= xyzt
تعليقات
- السطر 3 من الكود: يتم التعامل مع الكائن عبر مؤشر. لذا فإن [obj1] هو مؤشر. تعديل الكائن المشار إليه لا يغير المؤشر [obj1]. ولهذا السبب، كما هو الحال مع المصفوفات، يتم إعلان مرجع الكائن باستخدام الكلمة الرئيسية [const]؛
- السطر 6 من الكود: كما هو الحال مع المصفوفات، فإن [console.log] قادر على عرض الكائنات؛
- السطر 11 من الكود: يمكن إعادة كتابة obj1.prop3 على النحو التالي: obj1.[‘prop3’]. وتكون هذه الصيغة الأخيرة مفيدة عندما تكون «prop3» متغيرًا بالفعل (السطران 20-21)؛
- الأسطر 13-18 من الكود: توضح أن الأمر [obj2=obj1] هو نسخة مرجعية للكائن وليس الكائن نفسه؛
5.2. نص برمجي [obj-02]
يُظهر هذا البرنامج النصي أن خصائص الكائن يمكن أن تكون قيمتها كائنًا. وبذلك نحصل على كائنات متعددة المستويات. كما يتم إدخال الكائن العام [JSON] الذي يسمح بإجراء تحويلات بين الكائنات وسلسلة الأحرف.
'use strict';
// كائن متعدد المستويات
const personne = {
prénom: "martin",
âge: 12,
père: {
prénom: "paul",
âge: 45
},
mère: {
prénom: "micheline",
âge: 42
}
}
// الوصول إلى الخصائص
console.log("prénom personne=", personne.prénom);
console.log("prénom mère=", personne.mère.prénom);
personne.mère.âge = 40;
console.log("âge mère=", personne.mère.âge);
// console.log يعرف كيفية عرض الكائنات
console.log("personne=", personne);
console.log("mère=", personne.mère);
// يمكن أيضًا عرض سلسلة jSON الخاصة بالكائن
let json = JSON.stringify(personne);
console.log("jSON=", json);
// يمكن إعادة قراءة jSON
let personne2 = JSON.parse(json);
console.log("père=", personne2.père);
تعليقات
- السطر 24: تحويل كائن جافا سكريبت إلى سلسلة jSON؛
- السطر 27: تحويل سلسلة jSON إلى كائن جافا سكريبت؛
التنفيذ
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\objets\obj-02.js"
prénom personne= martin
prénom mère= micheline
âge mère= 40
personne= { 'prénom': 'martin',
'العمر': 12،
'الأب': { 'الاسم الأول': 'بول', 'العمر': 45 },
'الأم': { 'الاسم الأول': 'ميشلين', 'العمر': 40 } }
mère= { 'prénom': 'micheline', 'âge': 40 }
jSON= {"prénom":"martin","âge":12,"père":{"prénom":"paul","âge":45},"mère":{"prénom":"micheline","âge":40}}
père= { 'prénom': 'paul', 'âge': 45 }
تعليقات
- السطر 10: في سلسلة jSON، يجب أن تكون الخصائص محاطة بعلامات اقتباس، وكذلك القيم من نوع سلسلة الأحرف؛
5.3. نص برمجي [obj-03]
يقدم هذا البرنامج النصي مفهوم getter / setter لخاصية كائن:
'use strict';
// مُستقبلات ومُعيّنات كائن
const personne = {
// مُسترد
get nom() {
console.log("getter nom");
return this._nom;
},
// مُعيّن
set nom(unNom) {
console.log("setter nom");
this._nom = unNom;
}
};
// مُعيّن
personne.nom = "Hercule";
// مُسترد
console.log(personne.nom);
// الكائن نفسه
console.log("personne=", personne);
// هذا لا يمنع الوصول إلى الخاصية [_nom] مباشرة
personne._nom = "xyz";
console.log("personne=", personne);
تعليقات
- الأسطر 5-7: تعريف [getter]، وهي دالة تعرض عادةً قيمة خاصية الكائن ولكنها في الواقع يمكن أن تعرض أي شيء. يتم استبدال الكلمة الرئيسية [function] بالكلمة الرئيسية [get]؛
- السطر 7: تعرض الدالة getter الخاصية [_nom]. نلاحظ أن هذه الخاصية لا تحتاج إلى إعلان؛
- الأسطر 10-13: تعريف [setter]، وهي دالة تُعيّن عادةً القيمة المستلمة إلى خاصية للكائن، ولكنها في الواقع يمكن أن تفعل أي شيء. يتم استبدال الكلمة الرئيسية [function] بالكلمة الرئيسية [set]. يمكن استخدام [setter] للتحقق من صحة القيمة التي تم تمريرها كمعلمة إلى [setter]؛
- السطر 16: سيتم استدعاء الدالة [set nom] ضمناً؛
- السطر 18: سيتم استدعاء الدالة [get nom] ضمناً؛
- السطر 22: يوضح أن استخدام getter / setter يعتمد على رغبة المطور. إذا كان المطور يعرف اسم الخاصية التي تديرها هذه الوظائف، فيمكنه الوصول إليها مباشرةً؛
التنفيذ
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\objets\obj-03.js"
setter nom
getter nom
Hercule
personne= { nom: [Getter/Setter], _nom: 'Hercule' }
personne= { nom: [Getter/Setter], _nom: 'xyz' }
يُلاحظ في السطرين 5-6 أن [console.log] تعرض أيضًا الخصائص التي هي وظائف.
5.4. نص برمجي [obj-04]
يُظهر هذا البرنامج النصي ثلاث طرق لكتابة أسماء خصائص كائن وطريقتين للوصول إليها.
'use strict';
// يمكن أن تكون أسماء خصائص الكائن قيمًا ثابتة [nom]، أو محاطة بعلامات اقتباس أحادية ['nom']
// أو بين علامتي اقتباس ["nom"]
// القيم الثابتة
const obj1 = {
nom: "martin",
prénom: "jean"
};
console.log("prénom=", obj1.prénom);
// محاطة بعلامات اقتباس مفردة
const obj2 = {
'الاسم: "martin"،
'الاسم الأول: "jean"
};
console.log("nom=", obj2.nom);
// محاطة بعلامات اقتباس
const obj3 = {
"nom": "martin",
"prénom": "jean"
};
// طريقتان ممكنتان للوصول إلى الخاصية [nom]
console.log("nom=", obj3.nom);
console.log("nom=", obj3['nom']);
التنفيذ
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\objets\obj-04.js"
prénom= jean
nom= martin
nom= martin
nom= martin
5.5. البرنامج النصي [obj-05]
يوضح البرنامج النصي أن خصائص كائن حرفي يمكن أن تكون وظائف. وبذلك نكون قريبين جدًا من كائن مثيل الفئة، حيث توجد خصائص وأساليب.
'use strict';
// يمكن أن يكون للكائن خصائص من النوع [function]
const personne = {
// خصائص
prénom: "martin",
âge: 12,
père: {
prénom: "paul",
âge: 45
},
mère: {
prénom: "micheline",
âge: 42
},
// طريقة
toString: function () {
return JSON.stringify(this);
}
}
// الاستخدام
console.log("personne=", personne);
console.log("personne.toString=", personne.toString());
- الأسطر 17-19: طريقة داخلية للكائن. في هذه الطريقة، يتم الوصول إلى خصائص الكائن عبر الكلمة الرئيسية [this] (السطر 18). تشير [this] إلى الكائن نفسه، وتشير [this.prénom] إلى خاصية [prénom] الخاصة به؛
التنفيذ
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\objets\obj-05.js"
personne= { 'prénom': 'martin',
'العمر': 12،
'الأب': { 'الاسم الأول': 'بول', 'العمر': 45 },
'الأم': { 'الاسم الأول': 'ميشلين', 'العمر': 42 },
toString: [Function: toString] }
personne.toString= {"prénom":"martin","âge":12,"père":{"prénom":"paul","âge":45},"mère":{"prénom":"micheline","âge":42}}
5.6. نص برمجي [obj-06]
يوضح هذا البرنامج النصي كيفية الوصول إلى خصائص كائن ما عندما لا يكون اسمها معروفًا مسبقًا.
'use strict';
// يمكن أن يكون للكائن خصائص من النوع [function]
let personne = {
// خصائص
prénom: "martin",
âge: 12,
père: {
prénom: "paul",
âge: 45
},
mère: {
prénom: "micheline",
âge: 42
},
// طريقة
toString: function () {
return JSON.stringify(this);
}
}
// الاستخدام
console.log(personne);
// خصائص
console.log("-----------------------");
for (const key in personne) {
if (personne.hasOwnProperty(key)) {
const element = personne[key];
console.log(key, "=", element);
}
}
// لتجنب تحذير eslint (1)
console.log("-----------------------");
for (const key in personne) {
if (Object.prototype.hasOwnProperty.call(personne, key)) {
const element = personne[key];
console.log(key, "=", element);
}
}
// لتجنب تحذير eslint (2)
console.log("-----------------------");
for (const key in personne) {
// eslint-disable-next-line no-prototype-builtins
if (personne.hasOwnProperty(key)) {
const element = personne[key];
console.log(key, "=", element);
}
}
تعليقات
- الأسطر 26-31: الكود الذي يسمح بالحصول على قائمة خصائص كائن ما، بدون الأساليب. هذا الكود موضوع تحذير من ESLint:

- الأسطر 32-39: الكود الذي يسمح بتجنب تحذير ESLint. نمر عبر النموذج الأولي للفئة [Object]؛
- الأسطر 41-47: أو نكتفي بتعطيل التحذير (السطر 43)؛
5.7. نص برمجي [obj-07]
يُظهر البرنامج النصي [obj-07] إمكانية تفكيك كائن:
'use strict';
// إزالة البنية
// القيم الثابتة
const obj1 = {
nom: "martin",
prénom: "jean"
};
// تفكيك obj1 في المتغيرات [n,p]
const { nom: n, prénom: p } = obj1;
console.log("n=", n, "p=", p);
// تفكيك obj1 في متغيرات [n2,p2]
function f({ nom: n2, prénom: p2 }) {
console.log("f-n2=", n2, "f-p2=", p2);
}
f(obj1);
// تفكيك obj1 في متغيرات [nom,prénom]
function g({ nom: nom, prénom: prénom }) {
console.log("g-nom=", nom, "g-prénom=", prénom);
}
g(obj1);
// تفكيك obj1 في المتغيرات [nom,prénom]
// مع ترميز مختصر مكافئ لـ h({الاسم:الاسم،الاسم الأول:الاسم الأول})
function h({ nom, prénom }) {
console.log("h-nom=", nom, "h-prénom=", prénom);
}
h(obj1);
تعليقات
- السطر 11: الأقواس {} هي التي تسمح بإزالة البنية. الصيغة
const { nom: n, prénom: p } = obj1
تنشئ متغيرين [n] و [p] وهي تعادل:
const n = obj1.nom
const p = obj1.prénom
يمكن قراءة الإعلان على النحو التالي:
const { nom => n, prénom => p } = obj1
للتذكير بأن قيم سمات [nom, prénom] تذهب إلى المتغيرات [n, p]؛
- تتكرر عملية التفكيك في الأسطر 15 و21 و28. في كل مرة، يشير وجود الأقواس {} إلى أنه سيكون هناك تفكيك لكائن في متغيرات؛
- قد يكون السطر 28 مربكًا. إنه اختصار للترميز:
function h({ nom : nom, prénom : prénom })
نتائج التنفيذ هي كما يلي:
5.8. نص برمجي [obj-08]
يوضح البرنامج النصي [obj-08] كيفية الحصول على نسخة من كائن:
'use strict'
// استنساخ الكائنات
const obj1 = {
nom: "martin",
prénom: "jean"
};
// استنساخ (نسخ) obj1 باستخدام عامل التوزيع
const obj2 = { ...obj1 }
// التحقق
// obj2 يشير إلى نسخة من obj1
console.log("obj2===obj1 :", obj1 === obj2)
console.log("obj2=", obj2)
- السطر 10: عملية نسخ الكائن [obj1]. يُطلق على المشغل ... اسم مشغل الانتشار؛
نتائج التنفيذ هي كما يلي:
- السطر 1: يوضح أن المراجع [obj1] و [obj2] لا تشير إلى نفس الكائن؛
- السطر 2: يوضح أن الكائن الذي يشير إليه [obj2] هو نسخة من الكائن الذي يشير إليه [obj1]؛
5.9. Conclusion
أظهرت البرامج النصية في هذا القسم أن الكائن الحرفي في جافا سكريبت قريب من كائن مثيل الفئة في اللغات الموجهة للكائنات. يمكننا تعريف الخصائص والطرق وgetters / setters فيه. إنه كائن ديناميكي يمكننا تعريف خصائصه أثناء التنفيذ. يتصرف عندئذٍ كقاموس يمكن أن تكون عناصره من أي نوع، ولا سيما من النوع [fonction].