برمجة الكائنات Objects في جافاسكريبت


محمد أحمد العيل

مقدّمة نظرية

  • كائن جافاسكريبت هو كيان لديه خاصيّات. كلّ خاصيّة عبارة عن زوج مفتاح وقيمة. المفتاح هو اسم الخاصيّة.

  • يمكن أن تكون قيمة الخاصيّة بيانات (عددا، سلسلة محارف، …إلخ.) أو دالة. يُطلَق على الخاصيّة عندما تكون قيمتها دالة الاسم تابع Method.

  • يُنشَأ كائن حرفي Object literal في جافاسكريبت بتحديد خاصيّاته ضمن زوج من الأقواس المعكوفة.
const myObject = {
  property1: value1,
  property2: value2,
  // ... ,
  method1(/* ... */) {
    // ...
  },
  method2(/* ... */) {
    // ...
  }
  // ...
};
myObject.property1 = newValue; // يعيّن القيمة الجديدة للخاصيّة property1 في الكائن myObject 
console.log(myObject.property1); // يعرض قيمة الخاصيّة property1 في الكائن myObject
myObject.method1(...);           // استدعاء التابع method1 في myObject
  • تمثّل الكلمة المفتاحية this في تابع الكائن الذي يُستدعَى فيه التابع.
    
  • تعرّف لغة البرمجة سلفا كائنات عدّة للاستفادة منها مثل console و Math.

مقدّمة

ما هو الكائن؟

انظر إلى الكائنات في معناها غير البرمجي، مثل قلم. يمكن أن يكون للقلم ألوان عدّة، يصنعه أشخاص متعدّدون، أطراف متنوّعة وخاصيّات أخرى كثيرة.

على نحو مشابه، الكائن في البرمجة هو كيان لديه خاصيّات. تعرّف كل خاصيّة ميزة في الكائن. يمكن أن تكون الخاصيّة بيانات مرتبطة بالكائن (لون القلم) أو إجراء (قدرة القلم على الكتابة).

ما علاقة هذا بالشفرة؟

البرمجة كائنية التوجّه Object-oriented programming (أو OOP اختصارا) هي طريقة لكتابة البرامج باستخدام الكائنات. يكتُب المبرمج - عند اتّباع هذه الطريقة - الكائنات، ينشئها ويعدّل عليها؛ تشكلّ الكائنات البرنامج.
**
تغيّر البرمجة كائنية التوجّه الطريقة التي تُكتَب وتُنظَّم بها البرامج. كتبنا في الفصول السابقة برامج تعتمد على الدوالّ، وهي طريقة برمجيّة تُسمَّى البرمجة الإجرائية Procedural programming. فلنكتشف الآن كيف نكتب شفرة كائنية التوجّه.

جافاسكريبت والكائنات

تدعم جافاسكريبت، مثل لغات برمجة أخرى، البرمجة بالكائنات. كما توفّر كائنات معرَّفة مسبقا مع إتاحة الفرصة لإنشاء كائنات جديدة.

إنشاء كائن

في ما يلي تمثيل جافاسكريبت لقلم حبر جاف أزرق اللون علامته التجارية Bic.

const pen = {
  type: "حبر جاف",
  color: "أزرق",
  brand: "Bic"
};

يمكن إنشاء كائنات جافاسكريبت، كما ذكرنا سابقا، بسهولة بتعيين خاصيّات الكائن ضمن زوج أقواس معكوفة {...}. كلّ خاصيّة هي زوج من المفاتيح والقيم. يُسمَّى الكائن المعرَّف سابقا بالكائن الحَرْفي Object literal.

ملحوظة: النقطة الفاصلة ; بعد زوج الأقواس اختيارية، إلا أنه من الآمن إضافتها على كلّ حال.

تعرِّف الشفرةُ أعلاه متغيّرا يُسمَّى pen قيمته كائن، يمكننا القول إذن إن pen كائن. لهذا الكائن ثلاث خاصيّات هي: type (النوع)، color (اللون) وbrand (العلامة التجارية). لكلّ خاصيّة اسمٌ وقيمة، كما أنها متبوعة بفاصلة لاتينية , (ما عدا الخاصيّة الأخيرة)

الوصول إلى خاصيّات الكائن

يمكن الوصول إلى قيم الخاصيّات بعد إنشاء الكائن بالتنويت النقطي Dot notation مثل myObject.myProperty.

const pen = {
  type: "حبر جاف",
  color: "أزرق",
  brand: "Bic"
};

console.log(pen.type);  // "حبر جاف"
console.log(pen.color); // "أزرق"
console.log(pen.brand); // "Bic"

الوصول إلى خاصيّة كائن هو عبارة Expression تنتج قيمة. يمكن تضمين هذه العبارة في عبارات أكثر تعقيدا. يوضّح المثال التالي كيفية عرض خاصيّات القلم السابق في تعليمة واحدة:

const pen = {
  type: "حبر جاف",
  color: "أزرق",
  brand: "Bic"
};

console.log(`أكتب بقلم ${pen.type} لونه ${pen.color} وعلامته التجارية ${pen.brand}`);

chapter06-01.png

التعديل على كائن

يمكن تعديل قيم الخاصيّات في كائن بعد إنشائه بالصيغة myObject.myProperty = newValue.

const pen = {
  type: "حبر جاف",
  color: "أزرق",
  brand: "Bic"
};

pen.color = "أحمر"; // تغيير لون القلم 

console.log(`أكتب بقلم ${pen.type} لونه ${pen.color} وعلامته التجارية ${pen.brand}`);

chapter06-02.png

توفّر جافاسكريبت إمكانية الإضافة الديناميكية لخاصيّات جديدة لكائن أنشأته قبْلا:

const pen = {
  type: "حبر جاف",
  color: "أزرق",
  brand: "Bic"
};

pen.price = "2.5"; // تعيين خاصية لسعر القلم
console.log(`يبلغ سعر قلمي ${pen.price}`);

chapter06-03.png

البرمجة بالكائنات

تعلّم الكثير من الكتب والدورات البرمجة كائنية التوجّه عبر أمثلة عن الحيوانات، السيّارات أو الحسابات المصرفية. فلنجرّب أمرا ألطف ولننشئ لعبة تقمّص أدوار Role playing game مصغَّرة باستخدام الكائنات.

تُعرَّف كلّ شخصية في ألعاب تقمّص اﻷدوار بصفات مميَّزة عدّة مثل القوّة، القدرة على التحمّل والذكاء. في ما يلي لقطة شاشة للعبة تقمّص أدوار شهيرة على الإنترنت.

chapter06-04.png

سيكون للشخصيّات - في مثالنا الأبسط كثيرا - ثلاثُ صفات مميّزة:

  • الاسم Name،
  • الصّحة Health (عدد نقاط الحياة)،
  • القوة Strength.

مثال ساذج

فلنقدّم أورورا، الشخصيّة الأولى في لعبتنا لتقمّص الأدوار:

const aurora = {
  name: "أورورا",
  health: 150,
  strength: 25
};

للكائن aurora ثلاث خاصيّات: health، name وstrength.

ملاحظة: يمكن - كما ترى في المثال أعلاه - إسناد أعداد، سلاسل محارف وحتى كائنات أخرى إلى خاصيّات الكائنات.

تستعدّ أورورا للبدء في سلسلة من المغامرات العظيمة التي ستحدّث بعض منها خاصيّات الشخصيّة. تأمل المثال التالي:

const aurora = {
  name: "أورورا",
  health: 150,
  strength: 25
};

console.log(`يوجد لدى ${aurora.name} نقاط قوة قدرها ${aurora.health} وقوة تبلغ  ${aurora.strength}`);

// أصاب سهم أورورا وبالتالي تقل نقاط الحياة
aurora.health -= 20;

// تتجهّز أورورا بقلادة قوة
aurora.strength += 10;

console.log(`يوجد لدى ${aurora.name} نقاط قوة قدرها ${aurora.health} وقوة تبلغ  ${aurora.strength}`);

chapter06-05.png

التعريف بالتوابع

احتجنا في الأمثلة السابقة إلى كتابة تعليمات console.log طويلة في كلّ مرة نريد عرض حالة الشخصية. توجد طريقة أنسب للوصول إلى هذا الغرض.

إضافة تابع لكائن

تأمل المثال التالي:

const aurora = {
  name: "أورورا",
  health: 150,
  strength: 25
};

// ترجع وصف الشخصية
function describe(character) {
	return `يوجد لدى ${character.name} نقاط صحة قدرها  ${character.health} وقوة تبلغ ${character.strength}`;
}

console.log(describe(aurora));

chapter06-06.png

معامل الدالة describe() هو كائن. تصل الدالة إلى خاصيّات الكائن وتنشئ سلسلة المحارف التي تصف الشخصية.

أدناه مقاربة بديلة تستخدم الدالة describe() داخل الكائن.

const aurora = {
  name: "أورورا",
  health: 150,
  strength: 25,

 // ترجع وصف الشخصية
function describe(character) {
	return `يوجد لدى ${character.name} نقاط صحة قدرها  ${character.health} وقوة تبلغ ${character.strength}`;
}
};

console.log(aurora.describe());

chapter06-07.png

يتوفّر الكائن الآن على خاصيّة جديدة: describe(). قيمة هذه الخاصيّة دالة تُرجِع وصفا نصيًّا للكائن. نتيجة التنفيذ مطابقة تماما لما سبق.

تُسمّى خاصيّة كائن عندما تكون قيمتها دالة بالتابع. تُستخدَم التوابع لتعريف إجراءات على كائن. يضيف التابع سلوكا إلى الكائن.

استدعاء تابع في كائن

فلنتأمل السطر الأخير من المثال السابق:

 
console.log(aurora.describe());

نستخدم العبارة aurora.describe() لعرض وصف الشخصية بدلا من describe(aurora)، وهنا فرق جوهري.

  • تستدعي العبارة describe(aurora) الدالة describe() مع تمرير الكائن aurora في المعطيات. الدالة خارجة عن الكائن. هذا مثال على البرمجة الإجرائية.
  • تستدعي العبارة aurora.describe() الدالة describe() في الكائن aurora. الدالة خاصيّة من خاصيّات الكائن: تابع. هذا مثال على البرمجة كائنية التوجه.

صيغة استدعاء التابع myMethod() في myObject هي myObject.myMethod().

تنبيه: تذكّر الأقواس، حتى وإن كانت خاوية، عند استدعاء تابع.

الكلمة المفتاحية this

تأمل جيّدا متن التابع describe() في المثال التالي:

const aurora = {
  name: "أورورا",
  health: 150,
  strength: 25,

  // ترجع وصف الشخصية
  describe() {
	  return `يوجد لدى ${this.name} نقاط صحة قدرها  ${this.health} وقوة تبلغ ${this.strength}`;
  }
};

سترى كلمة مفتاحية جديدة: this. تُعيَّن هذه الكلمة المفتاحية تلقائيا داخل تابع في جافاسكريبت وتمثّل الكائن الذي استُدعِي فيه التابع.

لا يستقبل التابع describe() أي معاملات. يستخدم التابع this للوصول إلى خاصيّات الكائن الذي استُدعِي فيه.

الكائنات المعرَّفة مسبقا في جافاسكريبت

تتوفّر جافاسكريبت على كائنات عدّة معرَّفة مسبقا تخدم أغراضا متفرّقة. رأينا في ما مضى بعضا منها:

  • يمنح الكائن console الوصول إلى بيئة الطرفية. التعليمة console.log() هي في الواقع استدعاء لتابع.
  • يحوي الكائن Math خاصيّات رياضية كثيرة. على سبيل المثال، تُرجع الخاصيّة Math.PI قيمة تقريبية للعدد π، ويرجع التابع Math.random() عددا عشوائيا بين 0 و1.

حان وقت كتابة الشفرة!

إضافة تجربة الشخصية

حسّن برنامج لعبة تقمّص الأدوار بإضافة خاصيّة التجربة؛ على أن يكون اسمها xp وقيمتها الابتدائية 0. يجب أن تظهر التجربة ضمن وصف الشخصية.

// للإنجاز: إنشاء الكائن character هنا.

// أصاب سهم أورورا وبالتالي تقل نقاط الحياة
aurora.health -= 20;

// تتجهّز أورورا بقلادة قوة
aurora.strength += 10;

// تعلّمت أورورا مهارة جديدة
aurora.xp += 15;

console.log(aurora.describe());

chapter06-08.png

نمذجة Modeling كلب

أكمل البرنامج التالي لإضافة تعريف بالكائن dog (كلب).

// للإنجاز: أنشئ الكائن dog هنا 

console.log(`${dog.name} كلب نوعه ${dog.species} يبلغ طوله ${dog.size}`);
console.log(`انظر هرّة! ${dog.name} ينبح: ${dog.bark()}`);

chapter06-09.png

نمذجة دائرة

أكمل البرنامج التالي لإضافة تعريف الكائن circle (دائرة). يُدخل الزائر قيمة شعاع الدائرة

const r = Number(prompt("أدخل قيمة شعاع الدائرة:"));

// للإنجاز: أنشئ تعريف الدائرة هنا

console.log(`يبلغ محيط الدائرة ${circle.circumference()}`);
console.log(`تبلغ مساحة الدائرة ${circle.area()}`);

نمذجة حساب مصرفي

أنشئ برنامجا ينشئ كائن account يمثّل حسابا مصرفيا لديه الميزات التالية:

  • خاصيّة name قيمتها “أحمد”.
  • خاصيّة balance قيمتها 0.
  • تابع credit تضيف القيمة (سالبة أو موجبة) المُمرَّرة في المعطى إلى رصيد الحساب balance.
  • تابع describe يُرجع وصف الحساب.

استخدم هذا الكائن لعرض وصف حساب مصرفي، أضف 250 إلى رصيده، اسحب منه 80 ثم اعرض وصفه مرة أخرى.

تحصُل على الآتي عند عرض وصف البرنامج في المرة الأولى:

“المالك: أحمد، الرصيد: 0”

وعلى ما يلي في المرة الثانية:

“المالك: أحمد، الرصيد: 170”

ترجمة - بتصرّف - للفصل Create your first objects من كتاب The JS Way.





تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن