جدول المحتويات
الكائنات
في هذا الفصل سنتعرف على مفهوم الكائن object و كيف أن الجافا سكريبت تتكون من مجموعة من الكائنات و أيضا سنتعلم كيفية إنشاءالكائنات . [تحسين] مقدمة في الكائنات
ذكرت في المقدمة أن الجافا سكريبت Object-oriented أي موجهة للكائنات .و مفهوم الـ Object-oriented مفهوم موجود في كل لغات البرمجه الحديثه و إن كنت قد تعاملت مع أحد اللغات الموجهة للكائنات مثل Java أو C# أو حتى php الإصدار الخامس فإن الأمر سيكون سهلا بالنسبة لك مع الجافا سكريبت ,مع العلم بأن الأمر مختلفا قليلا فيها و أيضا إن تعلمت البرمجة بالكائنات في الجافا سكريبت فأنت بالتالي تعلمت جزء كبير من البرمجة بالكائنات في أي لغة أخرى , و هناك بعض المميزات الغير متاحه فيها من تلك المتوفره في اللغات التي ذكرناها . و لكي تفهم ماذا يعني المفهوم لنتعرف أولا على ما هو الكائن Object Object:هو مجموعة من الدوال (functions) و المتغيرات (variables)الخاصة بها, مجموعة معا في شيء واحد هذا الشيء يسمى الكائن Object. بحيث أن تكون كل هذه الدوال تقوم بمهمات تشترك حول محور معين أو مهمة معينه .و لكي يتضح لك الأمر سأجسده لك بشيء من الواقع جهاز الكومبيوتر الذي تعمل عليه مثلا يمنكك إعتباره يمثل كائن ,و ستجد أن جهاز الكومبيوتر يتكون من عدة مكونات كل مكون يقوم بوظيفة معينه فالسماعات تصدر الصوت و الشاشه تظهر الصورة و لوحة المفاتيح تكتب عليها.. إلخ .و بإجتماع هذه المكونات و التي تشبه الدوال في البرمجه معا يكون الكومبيوتر.كذلك بإجتماع مجموعة من الدوال التي تقوم كل منها بوظيفة معينه يكون الكائن . مفهوم الـ Object-oriented يقوم على تقسيم البرنامج الذي نقوم بعمله إلى مجموعة من الكائنات و لذلك عدة مميزات سنذكرها في آخر الدرس.أما الآن فلننظر عمليا لما هو الكائن في الجافا سكريبت .و لكن قبل ذلك لا بد أن أذكر لك أن الكائنات تنقسم إلى نوعين :
[تحسين] الكائنات الموجودة مسبقا
في البداية سنتحدث عن الكائنات الموجودة أصلا في الجافا سكريبت ,حيث أن الجافا سكريبت تعتمد في عملها على مجموعة من الكائنات الموجوده بداخلها . في الدروس السابقة إستخدمنا كثيرا هذه الدالة document.write() إذا نظرت لهذه الدالة ستجد أنها تتكون من document ثم نقطة "."ثم write() . و الآن حان الوقت لتعلم أن document عبارة عن كائن Object هذا الكائن يحتوى داخله على مجموعة من المتغيرات و الدوال الخاصة بمحتوى صفحة الويب نفسها و منها الدالة write() التي استخدمناها كثيرا ,و هناك مفهومين خاصين بالكائنات لابد من ذكرهم الآن:
لكي تصل إلى دالة داخل كائن أو خاصية داخل كائن يجب أن تستخدم النقطة "." فتكتب أولا إسم الكائن ثم بعد النقطه
يمكن أن يكون كائن ما خاصية في كائن آخر أي أنه يمكن لكائن أن يحتوى كائن آخر داخله. و الآن انظر للمخطط الموجود بالأسفل و الذي يوضح الكائنات التي تتكون منها الجافا سكريبت مقسمة حسب نوعها ووظيفتها أنظر للشكل : الشكل يوضح المخطط الهرمي لللكائنات الموجودة أصلا في الجافا سكريبت و كل مستطيل في الشكل يمثل كائن كما ترى, تتفرع من بعض الكائنات كائنات أخرى ,و كما ترى أن هناك تقسيمين أساسين: Language :و يحتوي على كائنات خاصة باللغة نفسها وليست متعلقة بالمتصفح و محتويات الصفحة. و سنشرح اثنين من هذه الكائنات كمثال في هذا الفصل وهما math و date لكي يتضح لك من خلالهم بشكل أكبر ما هو الكائن عمليا وكيفية التعامل معاهم أما البقية فسيأتي دورهم في الفصول القادمه. navigator :و يحتوى على الكائنات الخاصة بالمتصفح و محتوياته . و أكثر ما يهمنا فيه هو الكائن document الذي يخص صفحة الويب نفسها وما تحتويه من النصوص و الصور و الحقول (forms) و الروابط و غيرها و سندرسه بالتفصيل في فصل خاص به فيما يسمى بالـ Dom . و الكائن window هو الذي يحتوى كل المتغيرات و الدوال التي تقوم بتعريفها مباشرة و يحتوى في داخله أيضا كل الكائنات الأخرى بمعنى : إن قمت بتعريف متغير هكذا var myname="molhm"فإنه يمكن إستدعاءه هكذا window. mynameأو قمت بتعريف دالة هكذا function myfunc(){ alert("hay"); }فإنه يمكن منادتها هكذا window.myfunc()و كذلك دالة alert التي قمنا بإستخدامها في السابق يمكن إستدعائها بهذه الطريقة window.alert()و لكن للأختصار و للتسهيل يكفي إستخدام إسم المتغير أو إسم الدالة عندما تكون موجودة مباشرة في الكائن window . فيكفي أن نكتب إسم المتغير أو إسم الدالة بدون أن يسبقه window. . أما لكي تصل لمتغير داخل كائن و الكائن هذا داخل كائن أكبر فيكون الأمر هكذا و لنفترض أننا نريد أن نصل إلى خاصية (أي متغير )داخل الكائن form حسب المخطط بالأعلى فإنه يمكننا ذلك بهذه الطريقة . document.forms.إسم الخاصية و ستتضح الأمور أكثر بعد أن ندرس بعض الأمثلة على الكائنات [تحسين] Math
ربما مازال الأمر غامضا بالنسبة لك و لست مدركا بالضبط لما هو الكائن ,أعتقد أنه من خلال هذا الدرس سيتضح لك أكثر ما هو الكائن ,فبشكل عام ستدرك أكثر معنى المفهوم ,كما ستتعلم كيف تتعامل مع الكائنات الموجودة في اللغة مسبقا عامة ,و ستتعرف بشكل خاص على عدد من الخصائص و الدوال الموجودة في الكائن Math و التي تختص بالعمليات الحسابية و حساب المثلثات . كما قلنا في البداية الكائن هو مجموعة من الدوال و المتغيرات المجموعة معا و تتمحور وظائفها حول موضوع معين و بالنسبة للكائن Math فإنه يحتوي على عدد من الخصائص "متغيرات" تمثل ثوابت رياضية هامة كما يحتوى على عدد من الدوال التي تقوم بعمليات حسابية هامة سنقوم الآن باستعراض بعضها .و ستجد أن ثمة شيء مشترك بينها جميعها انها كلها دوال و متغيرات خاصة بالعمليات الحسابية و الرياضيات .
و كما قلنا الخصائص هي المتغيرات و كما قد يوجد في المتغيرات التي نعرفها بنفسنا أرقام أو نصوص كذلك بالنسبة للمتغيرات الموجودة في كائنات معرفة مسبقا,و هنا الخصائص الموجودة في هذا الكائن عبارة عن ثوابت رياضية معروفة سنستعرض واحد منها و سنهمل بقية الثوابت لأنه من النادر جداأن تحتاج لها في برمجة الويب كما أنها قد لا يفهمها البعض ممن ليس لهم معرفة جيده بالرياضيات.
وهو االثابت المشهور الذي نستخدمه في حساب محيط الدائرة و مساحتها و نسميه "ط" و قيمته 22/7 و القيمة الموجودة في الجافا سكريبت له هي القيمة العشرية مقربه لخمسة عشر رقم بعد العلامة العشرية 3.141592653589793 و نستدعيه هكذا Math.PI و كما من المفترض أننا جميعا نعلم أن محيط الدائرة يحسب من خلال القانون PI*Dأي حاصل ضرب القطر في قيمة الثابت "ط" ولذا إن أردنا عمل برنامج لحساب محيط دائرة فإنه يكون كالتالي: PI
و كما ترى في المثال إستخدمنا الثابت هنا في هذا السطر :
return Math.PI * diameter
لاحظ أن الحروف لابد أن تكون "كابيتال" أي أنك لو كتبته هكذا pi لن يعمل كما أنه أيضا حرف الM في Math لا بد أن يكون "كابيتال".
يوجد أيضا معلومتين جديدتين في هذا المثال الأداة typeof و هي تستخدم في معرفة نوع البينات الموجود فيما بعدها و هنا بإستخدام
هذا التعبير
typeof diameter == "number"
فإننا نتأكد من الدخل رقم و أنظر للقيم التي ترجعها typeof في الحالات المختلفة .
<html> <script> var dia=parseInt(prompt("Enter the diameter")) function circumference(diameter) { if (typeof diameter == "number" && diameter >= 0) return Math.PI * diameter } alert("the circumference is :"+ circumference(dia) ) </script> </html> حاول بنفسك »اضغط على "حاول بنفسك" لكى ترى كيف تعمل فى الحقيقة typeof 4 ترجع "number" typeof "man" ترجع "string" typeof alert ترجع "function" typeof Math ترجع "object"الشيء الآخر الجديد هو إستخدام الأداة && في هذا السطر : if (typeof diameter == "number" && diameter >= 0) وقد ذكرنا من قبل أن هذه الأداة && أي "and" بمعنى "و" تجعل الناتج يكون صحيحا فقط في حالة أن يكون ما على يمينها صحيحا و ما على يسارها صحيحا و لذا فإن الشرط هنا لا يتحقق إلا إذا كان القطر diameter رقم و أيضا أكبر من أو يساوي الصفر بمعنى انه لابد من تحقق الشرطين معا .و يمكن إستخدام الإداة || أي or بمعنى "أو" بنفس الأسلوب إن كنت تريد أن ينفذ الأمر إن تحقق شرط من الشروط فقط . ثانيا:الطرق. و كما قلنا بالسابق ايضا أن الدوال الموجودة داخل الكائن تسمى باالطرق methods و سنستعرض بعض الدوال الموجوده في الكائن Math الآن.ceil() هذه الدالة تستقبل رقم و ترجع الرقم نفسه إن كان رقم صحيحها مثل 9 مثلا أما إن كان فيه كسر مثل 9.1 فإنها ترجع الرقم الصحيح الأكبر منه و هو 10 و الأمثلة التالية توضح إستخدامها أكثر حيث توضح تنفيذ الدالة و الناتج:Math.ceil(16) == 16 Math.ceil(16.01) == 17 Math.ceil(–15.01) == –15 floor() هذه الدالة تستقبل رقم و ترجع الرقم نفسه إن كان رقم صحيحها مثل 9 مثلا أما إن كان فيه كسر مثل 9.1 فإنها ترجع الرقم الأصغر منه و هو 9 و الأمثلة التالية توضح إستخدامها أكثر حيث توضح تنفيذ الدالة و الناتج:Math.floor(16) == 16 Math.floor(16.01) == 16 Math.floor(–15.01) == –16 max(), min() كل دالة من هؤلاء تأخذ رقمين الأولى min() ترجع الأصغر بينما الثانية max() ترجع الرقم الأكبر كما بالأمثلة:Math.max(1, 2) == 2 Math.min(2, Math.abs(–2)) == 2 Math.min(2, –2) == –2 random() وهي دالة ترجع رقم عشوائية ما بين صفر وواحد و يكون بدقة 16 خانة فمثلا خرج هذه الحلقة :for (var i = 0; i < 5; ++i) { document.write(Math.random() + "<BR>") }قد يكون كالتالي: .924853870611902 .8248305636609181 .9539277224126104 .9806934571332098 .7639888801207115لاحظ أن الأرقام عشوائية و في كل مرة تنفذ الحلقة ستكون هناك أرقام مختلفه. هناك دوال عديدة أخرى مثل round(), و التي تقوم بالتقريب لأقرب رقم صحيح ,و مثل sqrt() التي تحسب الجذر التربيعي ,و cos() التي تحسب جيب تمام الزاويةو العديد من الدوال الأخرى الموجوده في هذا الكائن .و لن أذكرها كلها. لأن الهدف من الدروس أن تفهم كيف تسير الأمور و لن أعرض لك كل الدوال و كل شيء في كل شيء ,المهم أن تفهم كيف يسر الأمر و تكتب الأكواد و تجربها فليس هناك من يحفظ كل الدوال حيث يوجد لها مراجع عديدة ستجد فيها كل الدوال مع وظيفتها و سنتحدث عن ذلك في نهاية الدروس أما الآن فلننجرب تطبيق بمثال على الطرق الخاصة بالكائن Math. المثال التالي يقوم بعرض صورة من عدة صور بشكل عشوائي ومع كل تحديث للصفحة refresh ستتغير الصورة بدون أن يكون هناك نظام يحكم تغيرها ,و إن كنت تجرب المثال في محرر الأكواد الخاص بالموقع ,فلكي يحدث إعادة تحديث للكود فقط تحتاج بأن تضغط مرة في نافذة كتابة الكود و مرة في التي يظهر فيها . math methods <html> <script language="JavaScript"> var imageList=new Array(); imageList[0] = "src/image1.jpg" imageList[1] = "src/image2.jpg" imageList[2] = "src/image3.jpg" imageList[3] = "src/image4.jpg" var imageChoice = Math.floor(Math.random()*imageList.length); document.write("<img src= "+ imageList[imageChoice] + ">") </script> </html> حاول بنفسك »اضغط على "حاول بنفسك" لكى ترى كيف تعمل فى الحقيقة و عندما نحلل الكود سنجد أننا في البداية أنشأنا مصفوفه فيها أسامي و مسارات الصور التي سيتم التبديل بينها و تتكون المصفوفه من اربع عناصر ,(لاحظ أن مسارات الصور هنا "src/image1.jpg" ستستبدلها أنت بالأماكن التي توجد فيها الصور على جهازك إن كنت ستكتب الكود في محرر نصوص لديك غير الخاص بالموقع). ثم بعد ذلك يوجد كود مهمته أنه ينتج عدد صحيح من صفر حتى ثلاثه بشكل عشوائي وهو هذا الكود var imageChoice = Math.floor(Math.random()*imageList.length); و يعمل هذا الكود كالتالي: imageList.length الخاصية length من الخواص التي تستخدم مع المصفوفات و مهمتها أن ترجع عدد عناصر المصفوفه و هنا سيرجع لنا العدد أربعه 4. Math.random()و قد تحدثنا عنها بالأعلى و سوف تنتج رقم ما بين الواحد و الصفر و لذلك فإن حاصل ضرب ناتج هذه الدالة في العدد 4 الذي ينتج من imageList.length دائمارقم عشوائي اقل من 4 و أكبر من الصفر . Math.floor() أما هذه الدالة فستقوم بحذف الكسر و بالتالي يصبح الرقم الناتج في النهاية رقم صحيح من صفر حتى ثلاثة و هي الأرقام التي تمثل ترتيب عناصر المصفوفه. أما السطر الأخير فإنه يطبع تاج هيتميل الذي يستخدم في إضافة الصور مع وضع قيمة المصفوفه بعد src و الذي يكون مسار الصورة. document.write("<img src= "+ imageList[imageChoice] + ">") و نتيجة تنفيذه إن كان قيمة imageChoice تساوي صفر تكون <img src=src/image1.jpg > و كما تعلم عندما تكتب هذا التعبير في Html فإنه يظهر الصورة التي مسارها بعد src. [تحسين] Date
الآن سنتعرف على كائن آخر من كائنات الجافا سكريبت و هو أيضا يمثل النوع الآخر من الكائنات ,حيث أن الكائنات في الجافا سكريبت تنقسم إلى نوعين :
و الفرق بينهم:
عندما كنا نستخدم خاصية أو دالة من دوال الكائن الإستاتيكي Math كنا نستدعيها مباشرة بهذه الطريقة : في حالة الخاصية مثل PI: يكون هكذا Math.PI في حالة الدالة مثل ceil : يكون هكذا Math.ceil() أما في حالة الكائنات الديناميكية مثل Date فلابد أن ننشيء instance أي "مثيل" و يتم ذلك بهذه الطريقة: var dateInstance = new Date()و هذا المثيل dateInstance هو عبارة عن كائن إستاتيكي . و هناك شيء تقني مهم : إذا إستخدمنا الأداة typeof و التي ترجع لنا النوع البينات مع الكائن الإستاتيكي Math و الكائن Date سنجد أنه يرجع لنا نتيجتين مختلفتين . في حالة Math: typeof Math يرجع لنا "object" . في حالة Date: typeof Date يرجع لنا "function" .أي أن الكائن الديناميكي ليس بالضبط كائن "object" لكنه دالة function من نوع خاص و سنلمس ذلك عمليا عندما نتعلم إنشاء الكائنات في الدروس التالية ,و الكائن الديناميكي مشابه للـ class في اللغات مثل php الاصدار الخامس و جافا وسي شارب و غيرها ,و إن لم تكن قد تعاملت مع أيا من اللغات الموجهة للكائنات من قبل فلا تشغل بالك بمصطلح الـ class فهو عامة شيء مشابه للكائن الديناميكي . ولاحظ أيضا أنه إذا إختبرنا نوع المثيل الذي ننشئه من الكائن الديناميكي سنجده "object" أي أن: var dateInstance = new Date() typeof dateInstance ترجع لنا "object"و من هنا ينشأ الفرق الذي تحدثنا عنه في البداية حيث أنه كل مثيل (كائن إستاتيكي ) ننشئه من الكائن الإستاتيكي مثل Date قد يحتوى على قيم مختلفة للمتغيرات ,وهذا ما سنوضحه بالمثال التالي . Date
كما ترى في المثال في السطر الأول أنشأنا كائن إستاتيكي now ثم قمنا بطباعة هذا الكائن في السطر التالي و ستجد
أنه الوقت الذي تم إنشاء الكائن فيه و لذا في كل مرة ستعيد تحديث الصفحة ستجد النتيجة تتغير للوقت الذي قمت عنده بالتحديث.
و هذا يوضح كيف أن البيانات داخله تتغير و لكن يبقى الهيكل العالم ثابت فكل كىئن ستنشئه من الأوبجكت الديناميكي سيكون له
نفس الخصائص Properties و نفس الدوال methods .و لندرس الآن بعض الدوال الخاصة به.
هناك نوعين من الدوال ستقابلهم بإستمرار في البرمجة الموجهة بالكائنات و هما دوال الـ getter و دوال الـ setter الأولى تأتي لك ببيانات من داخل الكائن و الثانية تغير قيم البيانات الموجوده في الكائن و لنستعرض بعض الدوال الخاصة بالكائن Date:
أولا: دوال الـ getter و هي تبدأ دائما ب get مثل:
getMonth():ترجع الشهر الموجود في الكائن الذي أنشأناه كما بالمثال و يرجعه على شكل رقم هو ترتيب الشهر
<html> <script language="JavaScript"> var now = new Date() document.write(now) </script> </html> حاول بنفسك »اضغط على "حاول بنفسك" لكى ترى كيف تعمل فى الحقيقة getMonth()
و بالمثل :
<html> <script language="JavaScript"> var now = new Date() var month = now.getMonth() var ar = new Array(12) ar[0] = "January" ar[1] = "February" ar[2] = "March" ar[3] = "April" ar[4] = "May" ar[5] = "June" ar[6] = "July" ar[7] = "August" ar[8] = "September" ar[9] = "October" ar[10] = "November" ar[11] = "December" var message = "It is now " + ar[month] + ", my favorite.<BR>" document.write(message) </script> </html> حاول بنفسك »اضغط على "حاول بنفسك" لكى ترى كيف تعمل فى الحقيقة getYear(): يرجع السنه بالأرقام ,في بعض المتصفحات يرجع ثلاث أرقام فقط مثلا يرجع 2011 هكذا 111 تجاهل الأخير من اليسار فيصبح لديك رقم السنه بعد الألفين . getDate():يرجع في أي يوم من الشهر نحن مثلا إن كان اليو 11 في الشهر يرجع 11. getDay():ترجع ترتيب اليوم بحيث أن يبدأ العد من أن يوم الأحد صفر. getHours():ترجع عدد الساعات من بعد منتصف الليل. و ستنكتفي بتلك الدوال من هذا علما بأنه يوجد غيرها لكن قلنا أن هدف الدروس أن تفهم الطريقة و ليس أن تحفظ وظائف الدوال .أما بالنسبة لدوال الـ setter و التي تبدأ دائما ب set فهناك setYear():و هذه الدالة تغير قيمة السنة داخل الكائن الذي قمت بإنشائه إلى القيمة التي تعطيها لها أي تضعها بين قوسي الدالة و لنفهمها من خلال هذا المثال الذي يعطيك أي يوم من أيام الأسبوع يقابل تاريخ اليوم الحاضر في السنة الماضية . setYear()
و كما ترى في هذا الجزء:
<html> <script language="JavaScript"> var now = new Date() var year = now.getYear() now.setYear(year - 1) ar = new Array(7) ar[0] = "Sunday" ar[1] = "Monday" ar[2] = "Tuesday" ar[3] = "Wednesday" ar[4] = "Thursday" ar[5] = "Friday" ar[6] = "Saturday" document.write("Last year, the current day was " + ar[now.getDay()]) </script> </html> حاول بنفسك »اضغط على "حاول بنفسك" لكى ترى كيف تعمل فى الحقيقة var now = new Date() var year = now.getYear() now.setYear(year - 1)في السطر الأول أنشأنا الكائن , ثم في الثاني حصلنا على تاريخ العام الحالي بالدالة getYear() أما في الثالث now.setYear(year - 1) فقد وضعنا المتغير الذي به العام الحالي و طرحنا منه واحد فيما بين قوسي الدالة setYear() و بهذا تم تغيير السنه داخل الكائن now إلى السنه الماضية ولذا عندنا سنطلب اليوم بالأسفل now.getDay() سيعطينا رقم اليوم المماثل في السنه الماضية و من المصفوفات بالأعلى يتم تسميته على حسب ترتيبه. و هناك أيضا دوال مشابهة مثل: setMonth():تغير الشهر في الكائن إلى الشهر الذي تعطيه لها . setDate():تغير تاريخ اليوم أي ترتيبه في الشهر إلى القيمة التي تعطيها لها و يوجد أيضا عدد آخر من الدوال تقوم بوظائف مشابهة كتغير الساعه و اليوم و هكذا و كلها تعمل بنفس الفكرة . من الأمثلة السابقة يجب أن نكون أدركنا كيف أنه الكائن الإستاتيكي الذي تنشئه من الكائن الديناميكي Date تتشكل البيانات فيه حسب وقت إنشاءه فيحتوى المعلومات التفصيلية للوقت الذي أنشئ فيه ,و بالإضافة لذلك يمكنك أيضا تتحكم في قيم البيانات الموجوده في الكائن عند إنشاءه و يتم ذلك بهذا الشكل: إن أردنا أن ننشئ كائن من Date فيه المعلومات التفصيلية لتاريخ نحن نريده و ليس تاريخ إنشاءه و ليكن مثلا "Sat Dec 25 2006" أي السبت الخامس و العشرين من ديسمبر عام 2006 الساعه التاسعه ونصف صباحا بالضبط فإنه يتم هكذاvar Xmas2006 = new Date(106,11,25,9,30,0) لاحظ ترتيب البرامترز فيما بين الأقواس يكون كالتالي: year, month, day, hour, minute, seconds و كذلك كما تعاملنا مع الكائن الديناميكي Date يكون الأمر مع الكائنات الديناميكية عامة بنفس الفكر.و الآن لننتقل إلى كيفية إنشاء الكائنات. [تحسين] إنشاء الكائنات بواسطة المبرمج
في الدروس السابقة وضحنا ما هي الكائنات و كيفية التعامل معها و كيف أن الجافا سكريبت تعتمد على مجموعة من الكائنات الموجودة في تكوين اللغة الأساسي .في هذا الدرس سنتعلم كيف نبني كائن ,ولكن لما نحتاج أن نبني كائن ؟؟سأكتفي الآن بأن أقول لك أن البرمجة الحديثة بإستخدام اللغات الموجهة للكائنات Object-Oriented تقوم على تقسيم البرنامج "الكود" الذي تكتبه إلى كائنات ,و لهذا مزايا سنتحدث عنها في آخر الفصل . سأقسم موضوع إنشاء الكائنات إلي قسمين هذا الدرس الذي سأشرح فيه الأساس في بناء الكائنات ,و الدرس التالي الذي سأشرح فيه بعض المهارات و المفاهيم الإضافية الهامة. أولا :إنشاء كائن إستاتيكي تعاملنا مع الكائن الإستاتيكي Math و الموجود داخل بناء الجافا سكريبت أصلا ,الآن سنتعلم كيف نصنع كائنا استاتيكا, و الأمر بسيط للغايه .حيث نستخدم هذه الطريقة : مثل تعريف المتغير نكتب إسم الكائن الذي نريده بعد var ثم بعد علامة الـ"=" نضع قوسي المجموعة . var objectname={ }بين قوسي المجموعة نضع الخواص و المتغيرات التي ستكون داخل الكائن و يتم و ضعها كالتالي : لإضافة خاصية نضع إسم الخاصية ثم العلامة : ثم البينات (أي القيمة التي تريدها للخاصية)هكذا propertyName:"value"لإضافة دالة تكتب إسم الدالة ثم العلامة : ثم function(البرامترز إن كان هناك) ثم قوسي المجموعة هكذا functionName:function(){} و لنأخد مثال عملي ليتضح الأمر أكثر و ليكن إنشاء كائن يحتوى على بيانات شخص إسمه و سنه و عمله ويحتوى على دالة تقوم بعرض تلك البيانات على الصفحه . إنشاء كائن استاتيكي
في الجزء الأعلى من الكود قمنا بإنشاء الكائن من خلال هذا الكود:
<html> <script language="JavaScript"> //create object var person={ name:"Ahmed", age:25, job:"Engineer", getProfile:function(){ var string="Name:"+this.name+"<br>"+"Age:"+this.age+"<br>"+"job:"+this.job; document.write(string) } } //call method. person.getProfile() //print value of a property. document.write("<hr>") person.name="mohamed" document.write("<br>The name becomes: "+person.name) document.write("<hr>") person.getProfile() </script> </html> حاول بنفسك »اضغط على "حاول بنفسك" لكى ترى كيف تعمل فى الحقيقة var person={ name:"Ahmed", age:25, job:"Engineer", getProfile:function(){ var string="Name:"+this.name+"<br>"+"Age:"+this.age+"<br>"+"job:"+this.job; document.write(string) } }و كما ستلاحظ : عرفنا الخواص بالطريقة التي ذكرناها مثل name:"Ahmed". بين كل خاصية و ما يليها أو دالة و ما يليها توضع فاصله "," إلا بعد آخر عنصر . عرفنا الدالة بالطريقة التي ذكرناها كما ترى getProfile:function(){ var string="Name:"+this.name+"<br>"+"Age:"+this.age+"<br>"+"job:"+this.job; document.write(string) }ستجد كلمة جديدة داخل الدالة و هي this و الأداة this لابد أن تسبق إسم المتغير الموجود داخل الكائن عندما تستخدمه داخل الكائن , لاحظ أنك عندما تستخدم المتغير خارج الكائن تذكر إسم الكائن قبله مثل person.name ولذا عندما تستخدم المتغير داخل الكائن فأنت تقول أنه في "هذا" الكائن الذي أنا داخله أي أن this تحل محل إسم الكائن داخله هكذا this.name بالأسفل إستدعينا الدالة person.getProfile() و التي تعرض لك النص الذي يظهر لك في الشاشه فيه الإسم و العمر و الوظيفة . في السطر الموجود بالأسفل قليلا غيرنا قيمة الخاصية name هكذا: person.name="mohamed" و لذا عندما قمنا بإستدعاء الدالة person.getProfile() ثانية ستجد ان الإسم المعروض تغير لmohamed و الآن لننتقل إلى إنشاء الكائنات الديناميكية. ثانيا :إنشاء الكائنات الديناميكية. تعاملنا في الدروس السابقة مع كائن ديناميكي و هو Date و عرفنا انه لكي تستخدمه لابد أن ننشئ "مثيل" instance بإستخدام الكلمة new و أن هذا المثيل يكون مثل الكائن الإستاتيكي و قد وجدنا أنه عندما نبحث عن نوع الكائن الديناميكي بإستخدام typeof Date فإننا نجد أنه دالة function . في هذا الدرس سنتعلم كيف ننشئ كائنا ديناميكا و ستجد أنه يتم إنشائه من خلال دالة تسمي بالـ Constructor Function و لكن ما هي الـ Constructor Function؟؟ بالنسبة للكائن الديناميكي الذي درسناه Date فإن الـ Constructor Function له هي Date() و التي عندما تنشئ مثيل منه "كائن إستاتيكي " بإستخدام كلمة new هكذا now =new Date() فإنها تُنفذ أو تستدعى و تقوم بتعريف الخواص و الدوال للكائن now ,وعملية إنشاء كائن ديناميكي تكون عبارة عن عملية تعريف الـ Constructor Function أي بشكل أبسط عملية إنشاء كائن ديناميكي هي عملية إنشاء دالة و لنوضح ذلك بالمثال .و ليكن إنشاء كائنا ديناميكا مشابها لذلك الإستاتيكي الذي أنشأناه و الذي يحتوى على بيانات شخص ما و دالة لعرضها. و يتم إنشاء هذا الكائن من خلال هذا الكود.إنشاء كائن ديناميكي
إذا نظرت إلى الكود الذي أمامك ستجد أننا:
عرفنا دالة تسمى person و قمنا بتعريف بعض البرامترز لها (name ,age,job) .
لإنشاء بعض الخواص type,name,age,job إستخدمنا كلمة this ثم أتبعناها بإسم الخاصية و سنجد أيضا أننا وضعنا كل خاصية مساوية لبرامتر من البرامترز التي عرفناها,ما عدا type و ضعنا لها قيمة ثابته و هي "profile"
<html> <script language="JavaScript"> //create object function person(p_name ,p_age,p_job){ this.type="profile" this.name=p_name this.age=p_age this.job=p_job this.getProfile=function(){ var string="Name:"+this.name+"<br>"+"Age:"+this.age+"<br>"+"job:"+this.job; document.write(string) } } ahmed=new person("ahmed","25","Engineer"); document.write(ahmed.type+"<hr>"); ahmed.getProfile() </script> </html> حاول بنفسك »اضغط على "حاول بنفسك" لكى ترى كيف تعمل فى الحقيقة this.type="profile" this.name=p_name this.age=p_age this.job=p_jobلتعريف دالة method في داخل الكائن إستخدمنا كلمة this ثم بعدها بنقطة وضعنا إسم الدالة ثم وضعنا لها تعبيرا يشبه تعريف الدالة لكن بدون وضع إسمها لأننا وضعناه قبل علامة ال "=" هكذا: this.getProfile=function(){ var string="Name:"+this.name+"<br>"+"Age:"+this.age+"<br>"+"job:"+this.job; document.write(string) }بعد تعريف دالة البناء Constructor Function يمكن أن تنشيء كائن إستاتيكي من خلال إستدعاء دالة البناء بإستخدام الكلمة new و هذا ما فعلنا بالسطر التالي : ahmed=new person("ahmed","25","Engineer");لاحظ هنا القيم الموضوعه "ahmed","25","Engineer" ستكون هي قيم p_name ,p_age,p_job على الترتيب و بالتالي ستوضع كقيم للخواص name,age,job على الترتيب من خلال و ضعها مساوية لـ this.name, this.age , this.job ,وهذا يوضح كيف يتم تحديد قيم المتغيرات (الخصائص) الموجوده في الكائن أثناء تعريفه أما قيمة الخاصية type فستبقى كما هي "profile" في كل الكائنات الإستاتيكية التي سننشأها من الكائن person لأننا وضعنا لها قيمة ثابتة في دالة البناء الأصلية . بعد تعريف الكائن person و عمل مثيل له ahmed يمكننا إستخدام الخواص و الدوال التي أصبحت موجوده في ahmed و هذا ما تم هنا : ففي هذا السطر طبعنا قيمة الخاصية type بالأضافة إلى خط أفقي : document.write(ahmed.type+"<hr>");و يجب أن تجدها كما وضعناها "profile" ثم بعد ذلك إستدعينا الدالة getProfile هكذا: ahmed.getProfile()و ستجد أنها طبعت على الصفحة البيانات التي تم إدخالها في دالة البناء person() كبرامترز عند إنشاء المثيل ahmed . هناك معلومة إضافية أعتقد أنه جاء الأوان لذكرها و هي أن الدوال و الكائنات عبارة عن أنواع من البيانات و لكن ماذا يعني أنهم أنواع من البيانات ؟؟ هذا يعني أنك يمكن أن تضع الدالة أو الكائن داخل متغير و لنوضح كيف يتم ذلك بالمثال : وضع دالة في متغير
ستجد في السطر الأول أننا وضعنا الدالة alert في المتغير mybox و لكن بدون أن نضع القوسين () بعدها حيث أن وضع القوسين بعد الدالة
يعني أنك تريد تنفيذها أما وضع إسمها فقط فهو يعني أنك تضع الدالة نفسها داخل المتغير فيصير كأنه هي و يتضح ذلك بالأسفل أننا قمنا بإستخدام mybox كأنها alert بالضبط و سيظهر لك صندوق به النص hay! .
و يمكننا أن نفعل نفس الشيء مع الكائن Date كما بالمثال :
<html> <script language="javascript" type="text/javascript"> var mybox=alert mybox("hay!"); </script> </html> حاول بنفسك »اضغط على "حاول بنفسك" لكى ترى كيف تعمل فى الحقيقة وضع كائن في متغير
و ستجد هنا أيضا أن المتغير mydate سيعمل بالضبط كأنه Date.
و السبب لذكري هذه المعلومة الآن هو أنها أولا تفسر جزء من الكود الخاص بإنشاء المتغير الديناميكي و هو هذا الجزء:
<html> <script language="javascript" type="text/javascript"> var mydate=Date now =new mydate() document.write(now) </script> </html> حاول بنفسك »اضغط على "حاول بنفسك" لكى ترى كيف تعمل فى الحقيقة this.getProfile=function(){ var string="Name:"+this.name+"<br>"+"Age:"+this.age+"<br>"+"job:"+this.job; document.write(string) } كما أنها ستكون مفيدة لفهم كثير مما سيأتي في الدروس التالية . [تحسين] بعض المهارات الإضافية في إنشاء الكائنات.
سنتعلم في هذا الدرس بعض المهارات الإضافية بالنسبة لإنشاء الكائن الديناميكي :
إنشاء الكائنات المتداخلة. و هو يعني أن تضع كائن كخاصية داخل كائن آخر كما بالمثال : الكائنات المتداخلة
<html> <script language="JavaScript"> function student(name, age, grade, father, mother) { this.name = name this.age = age this.grade = grade this.parents = new parents(father, mother) } function parents(father, mother) { this.father = father this.mother = mother } var student1 = new student("Ahmed", 16, 85, "Mohamed", "Asmaa") document.write(student1.name+"<br>") document.write(student1.age+"<br>") document.write(student1.grade+"<br>") document.write(student1.parents.father+"<br>") document.write(student1.parents.mother +"<br>") </script> </html> حاول بنفسك »اضغط على "حاول بنفسك" لكى ترى كيف تعمل فى الحقيقة
var student1 = new student("Ahmed", 16, 85, "Mohamed", "Asmaa")بعد إنشاء المثيل student1 نقوم بطبع قيم الخصائص من خلال هذه السطور document.write(student1.name+"<br>") document.write(student1.age+"<br>") document.write(student1.grade+"<br>") document.write(student1.parents.father+"<br>") document.write(student1.parents.mother +"<br>") student1.parents.father الطريقة الأخرى لإضافة الدوال في الكائنات: بدلا من أن نكتب تعريف الـmethods داخل تعريف الكائن كما فعلنا بالسابق يمكننا أن نعرف الدالة بالخارج و نستخدم إسمها في إضافتها للكائن كما بهذا المثال:<HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> function construct(name, val) { this[name] = val } function displayStudent() { var result = "" result += this.name + " -- " result += "a " + this.age + " - year old " result += this.grade + "% average student.<BR>" result += this.name + "'s parents -- " result += this.parents.father + ", " + this.parents.mother result += ".<BR>" document.write(result) } function student(name, age, grade, father, mother) { this.construct = construct this.display = displayStudent this.name = name this.age = age this.grade = grade this.parents = new parents(father, mother) } function parents(father, mother) { this.father = father this.mother = mother } var student1 = new student("Mohamed", 16, 85, "Ahmed", "Samir") student1.construct("friend", "Ali") document.write(student1.friend) document.write("<hr>"); student1.display() </SCRIPT> </HEAD> <BODY> </BODY> </HTML>
this.construct = construct this.display = displayStudent بعد إنشاء مثيل student1 يمكننا إستخدام الدوال المعرفة داخل الكائن ,ففي هذا السطر student1.construct("friend", "Ali")من خلال دالة construct أضفنا خاصية جديدة و هي friend و وضعنا قيمتها Ali ثم بعد ذلك قمنا بطباعة الخاصية document.write(student1.friend) أما في هذا السطر student1.display()فقد إستدعينا الدالة display التي قمنا بتعريفها بالطريقة الجديدة . Prototype النموزج Prototype : هو عبارة عن خاصية موجودة في أي كائن سواء كان معرف مسبقا في اللغة أو قام المبرمج بتعريفه ,و يمكن من خلال هذه الخاصية Prototype إضافة خواص أو دوال جديدة إلى الكائن كما سيتضح في المثال التالي.النموزج
تعلمنا من قبل أنه عندما تريد إنشاء نص فإنك تقوم بوضع النص بين علامتي تنصيص "" أو '' ثم تضعه في متغير
<HTML> <HEAD> <SCRIPT LANGUAGE="JavaScript"> var str1 = new String("a"), str2 = new String("b") function repeat(n, delimiter) { var text = "" var str = this.toString() // make sure the object is string while (n >= 0) { text += str text += delimiter n-- } return text } String.prototype.repeat = repeat // add a repeat() method to alert(str1.repeat(5, " ; ")) alert(str1) alert(str2.repeat(7, " ")) alert(str2.repeat(3,"+")) </SCRIPT> </HEAD> <BODY> </BODY> </HTML> حاول بنفسك »اضغط على "حاول بنفسك" لكى ترى كيف تعمل فى الحقيقة var str="text"هناك طريقة أخرى لإنشاء نص و هي من خلال الكائن String و هي هكذا: str=new String("text")و الفرق بين الطريقة الأولى و الثانية أنك إذا أختبرت نوع البيانات باستخدام typeof str في الأولى سيكون string و في الثانية سيكون object و في الحالتين يمكنك إستخدام جميع الخصائص و الدوال الخاصة بالكائن String . و في المثال ستجد أنه في البداية قمنا بإنشاء نصين بالطريقة الثانية . var str1 = new String("a"), str2 = new String("b")ثم قمنا بتعريف دالة تسمى repeat تقوم بتكرار النص عدد من المرات و التي من خلال الـprototype سنضيفها للكائن String و هذا السطر هو الذي يقوم بهذه المهمة : String.prototype.repeat = repeat و بإضافة الدالة من خلال الprototype للكائن فإنه يمكن إستخدامها مع أي مثيل مأخوذ منه و كما ترى قمنا في المثال بإستخدامها مع str1 و str2 و تظهر أهمية ال prototype في أنه يمكنك من إضافة دوال و خصائص إلى كائنات ديناميكية معرفة مسبقا مثل Date وString. [تحسين] مميزات البرمجة الموجهة للكائنات
الآن من المفترض أنك عرفت ما هي الكائنات و كيف تنشئها و لك الآن أن تعرف أن البرمجة الموجهة للكائنات object-oriented تقوم على أساس تقسيم البرنامج الذي نقوم بإنشاءه أو الإسكريبت إلى عدد من الكائنات ,و لكن ما فائدة ذلك ؟. سأشرح لك ما الفائده لكن ربما لن يكون الكلام واضحا و ذي معنى إلا بعد أن تجرب الأمر بنفسك, و لذا إن لم يكن الكلام مفهوما وواضحا بالنسبة لك لا تقلق فقط ضعه في بالك و عندما نصل إلى التطبيقات التي تظهر فيها أهمية و مميزات البرمجه الموجهة بالكائنات ستلمس معنى الكلام الذي سأقوله الآن. بالنسبة للبرامج الصغيرة التي قمنا بعملها بالسابق فإن عملية تقسيم تلك البرامج الصغيرة إلى كائنات تبدو بلا فائدة و أيضا متعبه أكثر من أن تقوم بعمل البرنامج بدون أن تقسمه إلى كائنات .و لكن في البرامج المعقده يصبح الأمر بالعكس حيث تكون البرمجه بالكائنات أفضل و أيضا أسهل . عندما تعمل على برنامج كبير بإستخدام البرمجة الموجهة للكائنات فإنك ستقسم البرنامج إلى عدة كائنات بحيث أن كل كائن سيحتوى على الدوال و البيانات التي تخص وظيفة معينه مثلا أنت تقوم بعمل سكريبت لصفحة ويب فتقوم بعمل كائن للتعامل مع القوائم و كائن للتعامل مع الحقول forms و كائن يخص مثلا التعامل مع حركات الماوس و ضغطات لوحة المفاتيح و هكذا .و فائدة تقسيم الكود بهذه الطريقة أولا أنه سيجعل الكود منظم أكثر و يمكنك إن أردت أن تعدل فيه أن تعدل فيه بسهولة . أما الفائدة الثانية أنك يمكنك إعادة إستخدام الكائنات في أكواد أخرى فعندما تقوم بعمل سكريبت لصفحة أخرى تحتوى مثلا على قائمة سيكون لديك الكائن الذي قمت بعمله سابقا و ستعيد إستخدامه بسهولة ..بدلا من أن تعيد البرمجه من الصفر ثانية . الفائدة الأهم و الميزة الأهم لتعلم البرمجة الموجهة بالكائنات و هي أن الـframeworks (المكتبات) مثل أشهرهم و هو jquery كلها تعتمد على نظام الكائنات و الframeworks إن لم تكن تعرفها هي عبارة عن أكواد جاهزة يمكنك إستخدامها بدلا من أن تبدأ من الصفر عندما تقوم بالبرمجه. فمثلا كثير جدا من المواقع تحتوي على صفحات لتسجيل عضوية جديده و بالتالي الموضوع شائع و كثيرون قامو بعمله من قبل فلماذا عندما تحتاج لأن تبرمج صفحة تسجيل عضوية جديدة في موقعك تبدأ من الصفر في حين أن هناك من فعلها قبلك؟ .و من هنا تأتي فائدة الframeworks في أنها تحتوى على أكواد كثيرة جدا تخص الوظائف التي يحتاجاها المبرمجون دائما .و في الواقع فإن لا أحد عندما يقوم ببرمجة موقع بالجافا سكريبت يبدأ من الصفر لكن الكل غالبا يستخدم الآن الـ jquery و فهم ما هي الكائنات و كيف تتكون يتم إنشائها سيساعدك جدا في التعامل مع مكتبة الـ jquery و التي سنشرحها في مجموعة دروس خاصة بها لكن الأساس هو الجافا سكريبت الذي نتعلمه في مجموعة الدروس الذي تدرسها الآن. |