diff options
Diffstat (limited to 'files/ar/learn/javascript/objects')
5 files changed, 1083 insertions, 0 deletions
diff --git a/files/ar/learn/javascript/objects/basics/index.html b/files/ar/learn/javascript/objects/basics/index.html new file mode 100644 index 0000000000..1d018b179b --- /dev/null +++ b/files/ar/learn/javascript/objects/basics/index.html @@ -0,0 +1,258 @@ +--- +title: اساسيات الكائن في جافاسكريبت +slug: Learn/JavaScript/Objects/Basics +translation_of: Learn/JavaScript/Objects/Basics +--- +<div>{{LearnSidebar}}</div> + +<div>{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}</div> + +<p class="summary" dir="rtl">في المادة الأولى من هذا الدرس سنتطرق إلى كائنات الجافا سكريبت، ثم سنلقي نظرة على التركيبة الأساسية لكائن الجافاسكريبت، ومن ثم إعادة النظر في بعض الميزات التي سبق وأن درسناها في وقت سابق من هذه الدورة التدريبية. علينا التأكيد أن العديد من الميزات التي قمت بالفعل بالتعامل معها هي في الحقيقة كائنات.</p> + +<table class="learn-box standard-table" dir="rtl"> + <tbody> + <tr> + <th scope="row">المتطلبات الأساسية:</th> + <td><span style="display: none;"> </span><span style="display: none;"> </span>دراية لا بأس بها بخصوص الحاسوب، الإلمام بمبادئ وأساسيات HTML و CSS، وبطبيعة الحال التمكن من أساسيات الجافاسكريبت (شاهد <a href="/en-US/docs/Learn/JavaScript/First_steps">First steps</a> وأيضا <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Building blocks</a>).<span style="display: none;"> </span><span style="display: none;"> </span></td> + </tr> + <tr> + <th scope="row">الهدف :</th> + <td>التمكن من فهم لغة البرمجة كائنية التوجه وكيف أن (" معظم الأشياء كائنات ") في الجافا سكريبت<br> + وأيضا الشروع في العمل مع كائنات الجافا سكريبت.</td> + </tr> + </tbody> +</table> + +<h2 dir="rtl" id="أساسيات_الكائن"><strong>أساسيات الكائن</strong></h2> + +<div style="font-size: 15px; font-family: 'tahoma';"> +<p dir="rtl">أولا وقبل كل شيء، قم بتحميل نسخة من الملف التالي <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs.html">oojs.html</a>. هذا الملف يتضمن العنصر — {{HTMLElement("script")}} سنستخدمه في كتابة الكود الخاص بنا، وعنصر الإدخال {{HTMLElement("input")}} سنستخدمه لإدخال بعض التعليمات البرمجية، وبعض المتغيرات والوظائف لاستخراج النتائج من حقل المدخلات ووضعها في العنصر {{HTMLElement("p")}}. سنستخدم هذه العناصر كأساس، لدراسة أساسيات بناء الكائن.</p> + +<p dir="rtl">كما هو الحال مع الكثير من الأشياء في جافا سكريبت، إنشاء كائن غالباً ما يبدأ بتعريف وتهيئة متغير.<br> + حاول إدخال التعليمة البرمجية أدناه في الملف الخاص بك، ثم قم بحفظ وتحديث:</p> + +<pre class="brush: js">var person = {};</pre> + +<p dir="rtl">قم بإدخال person إلى حقل المدخلات الخاص بك واضغط على الزر button، لتحصل على النتيجة التالية:</p> + +<pre class="brush: js">[object Object]</pre> + +<p dir="rtl">تهانينا، لقد أنشأت للتو أول كائن خاص بك. أنجزت المهمة! لكن هذا كائن فارغ، دعونا نقوم بتحديث هذ الكائن ليصبح على هذا الشكل:</p> + +<pre class="brush: js">var person = { + name : ['Bob', 'Smith'], + age : 32, + gender : 'male', + interests : ['music', 'skiing'], + bio : function() { + alert(this.name[0] + ' ' + this.name[1] + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.'); + }, + greeting: function() { + alert('Hi! I\'m ' + this.name[0] + '.'); + } +}; +</pre> + +<p dir="rtl">بعد الحفظ والتحديث، قم بإدخال التعليمات البرمجية التالية واحدة تلو الاخرى في حقل المدخلات الخاص بك:</p> + +<pre class="brush: js">person.name[0] +person.age +person.interests[1] +person.bio() +person.greeting() +</pre> + +<p dir="rtl">لقد حصلت الآن على بعض البيانات والوظائف من داخل الكائن الخاص بك، جميل! أصبحت الآن قادرا على الوصول إلى البعض من التركيبة الاساسية للكائن.</p> + +<div class="note" dir="rtl"> +<p><strong>ملاحظة </strong>: إذا واجهتك صعوبة في الحصول على هذا العمل، حاول مقارنة التعليمات البرمجية الخاصة بك مع النسخة لدينا، انظر <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-finished.html">oojs-finished.html</a> (يمكنك ايضا <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-finished.html">see it running live</a>). من الأخطاء الشائعة أثناء العمل مع الكائنات هو وضع فاصلة في نهاية آخر العضو — وهذا سوف يسبب خطأ.</p> +</div> + +<p dir="rtl">هذا ما يحدث هنا؟ لدينا كائن يتكون من عدة أعضاء، لكل واحد منهم اسماً (مثل name و age أعلاه)، وقيمة ( مثل ['Bob', 'Smith'] و 32). كل زوج (name: value) يجب أن يفصلا بفاصلة، والاسم والقيمة في كل حالة مفصولة بفاصلة منقوطة. فيما تكون دائماً، تركيبة الكائن الأساسية على هذا النحو :</p> + +<pre class="brush: js">var objectName = { + member1Name : member1Value, + member2Name : member2Value, + member3Name : member3Value +}</pre> + +<p dir="rtl">قيمة العضو في الكائن يمكن أن تكون أي شيء، في الكائن person لدينا سلسلة نصية، وقيمة رقمية، ومصفوفتان، ووظيفتان. العناصر الأربعة الأولى تسمى عناصر البيانات، ويشار إليها <strong>بخصائص الكائن </strong>(object properties). والعنصرين الأخيرين هما من الوظائف التي تسمح للكائن أن يفعل شيئا مع تلك البيانات، ويشار إليها <strong>بوظائف الكائن</strong> (object methods).</p> + +<p dir="rtl">يسمى هذا النوع من الكائنات بـ<strong> object literal</strong> — لقد كتبنا حرفيا محتويات الكائن إلى أن وصلنا إلى إنشائه. هذا على النقيض من الكائنات المبنية على الأصناف (classes)، والتي سوف نتطرق إليها في وقت لاحق.</p> + +<p dir="rtl">من الشائع جدا إنشاء كائن باستخدام object literal لنقل سلسلة من البيانات الهيكلية، البيانات المتصلة بطريقة ما، على سبيل المثال إرسال طلب إلى الخادم (server) لوضعها في قاعدة البيانات. إرسال كائن واحد سيكون أكثر كفاءة بكثير من إرسال عدة عناصر على حدة، وأسهل مقارنة بالعمل مع المصفوفة (Array)، حينما تريد تحديد عناصر فردية حسب الاسم.</p> + +<h2 dir="rtl" id="رمز_النقطة">رمز النقطة</h2> + +<p dir="rtl">أعلاه، يمكنك الوصول لخصائص الكائن ووظائفه باستخدام رمز النقطة.<br> + اسم الكائن (person) بمثابة <strong>namespace</strong> - يجب أن يتم ادراجه أولا قبل الوصول إلى أي شيء <strong>مغلف</strong> داخله. تليه النقطة، ثم يليها العنصر الذي تريد الوصول إليه - وهذا يمكن أن يكون اسم خاصية بسيطة، او عنصر من المصفوفة أو تنفيذ احدى وظائف الكائن، على سبيل المثال:</p> + +<pre class="brush: js">person.age +person.interests[1] +person.bio()</pre> + +<h3 dir="rtl" id="Sub-namespaces">Sub-namespaces</h3> + +<p dir="rtl">من الممكن تغيير شكل التعليمة البرمجية، من مصفوفة الى Sub-namespaces. على سبيل المثال، حاول تغيير اسم العضو من :</p> + +<pre class="brush: js">name : ['Bob', 'Smith'],</pre> + +<p dir="rtl">الى</p> + +<pre class="brush: js">name : { + first : 'Bob', + last : 'Smith' +},</pre> + +<p dir="rtl">على نحو فعال قمنا بانشاء Sub-namespaces. هذا يبدو معقدا، في الحقيقة هو ليس كذالك - للوصول إلى هذه العناصر كل ما تحتاج اليه هو ربط سلسلة العناصر بنقطة الترميز. جرب هذا :</p> + +<pre class="brush: js">person.name.first +person.name.last</pre> + +<p dir="rtl"><strong>هام</strong> : في هذه الحالة ستحتاج أيضا للذهاب الى الكود الخاص بك واستبدال الحالات التالية من :</p> + +<pre class="brush: js">name[0] +name[1]</pre> + +<p dir="rtl">الى</p> + +<pre class="brush: js">name.first +name.last</pre> + +<p dir="rtl">وإلا، فسوف لن تعمل الوظائف الخاصة بك.</p> + +<h2 dir="rtl" id="رمز_الاقواس">رمز الاقواس</h2> + +<p dir="rtl">هناك طريقة أخرى للوصول إلى خصائص الكائن – باستخدام رمز الاقواس. بدلاً من استخدام هذه :</p> + +<pre class="brush: js">person.age +person.name.first</pre> + +<p dir="rtl">يمكنك استخدام هذه</p> + +<pre class="brush: js">person['age'] +person['name']['first']</pre> + +<p dir="rtl">تبدو هذه الطريقة مشابهة جدا لكيفية الوصول إلى العناصر في المصفوفة، فعلا هي كذالك - بدلا من استخدام رقم الفهرس للوصول الى العنصر المطلوب، نستخدم اسم القيمة للوصول اليه. ليس مستغربا أن تسمى هذه الكائنات أحيانا بالمصفوفات الترابطية associative arrays - هذه السلاسل النصية تشير الى قيمها. نفس الشئ بالنسبة للمصفوفات حيث تشير الفهرسة الرقمية لقيمها.</p> + +<h2 dir="rtl" id="إعداد_اعضاء_الكائن">إعداد اعضاء الكائن</h2> + +<p dir="rtl">حتى الآن قمنا فقط <strong>بارجاع/ جلب</strong> اعضاء الكائن - يمكننا أيضا <strong>تعيين/تحديث</strong> اعضاء الكائن ببساطة عن طريق الإعلان عن العضو الذي نريد تحديثه سواء باستخدام النقطة أو برمز الاقواس، كالتالي :</p> + +<pre class="brush: js">person.age = 45 +person['name']['last'] = 'Cratchit'</pre> + +<p dir="rtl">في حقل المدخلات الخاص بك جرب ادخال التعليمات البرمجية التالية واحدة تلوى الاخرى للحصول على الاعضاء مرة أخرى بعد التحديث :</p> + +<pre class="brush: js">person.age +person['name']['last']</pre> + +<p dir="rtl">إعداد ألاعضاء لا يقتصر فقط على تحديث قيم الخصائص والوظائف القائمة، يمكنك أيضا إنشاء أعضاء جدد تماما. جرب هذا:</p> + +<pre class="brush: js">person['eyes'] = 'hazel' +person.farewell = function() { alert("Bye everybody!") }</pre> + +<p dir="rtl">يمكنك الآن اختبار ألاعضاء الجدد خاصتك :</p> + +<pre class="brush: js">person['eyes'] +person.farewell()</pre> + +<p dir="rtl">احد اهم الجوانب المفيدة في استخدام رموز الاقواس هو امكانية استخدامها ليس فقط لتحديد قيم الاعضاء، ولكن أسماء الأعضاء أيضا. دعونا نقول أننا نريد أن يتمكن المستخدم من تخزين قيمة مخصصة لبيانات الاشخاص، عن طريق كتابة اسم العضو وقيمته في اثنين من المدخلات النصية؟ يمكن أن نحصل على تلك القيم كالتالي :</p> + +<pre class="brush: js">var myDataName = nameInput.value +var myDataValue = nameValue.value +</pre> + +<p dir="rtl">يمكننا بعد ذلك إضافة اسم العضو الجديد وقيمته إلى الكائن person كالتالي :</p> + +<pre class="brush: js">person[myDataName] = myDataValue</pre> + +<p dir="rtl">لاختبار هذا، قم بإضافة الأسطر التالية أسفل التعليمات البرمجية خاصتك، بعد قوس الاغلاق للكائن person :</p> + +<pre class="brush: js">var myDataName = 'height' +var myDataValue = '1.75m' +person[myDataName] = myDataValue</pre> + +<p dir="rtl">الآن قم بحفظ وتحديث، وادخل ما يلي في حقل المدخلات الخاص بك :</p> + +<pre class="brush: js">person.height</pre> + +<p dir="rtl">وهذا لم يكن ممكناً مع طريقة نقطة الترميز، لانها تقبل اسم العضو كقيمة حرفية فقط، والتالي لا يمكن لهذه القيمة الحرفية ان تشير إلى اسم المتغير.</p> + +<h2 dir="rtl" id="ما_هي_this؟">ما هي this؟ </h2> + +<p dir="rtl">لربما لاحظت شيئا غريبا بعض الشيء في الوظائف الخاصة بنا؟. القي نظرة على هذه على سبيل المثال:</p> + +<pre class="brush: js">greeting: function() { + alert('Hi! I\'m ' + this.name.first + '.'); +}</pre> + +<p dir="rtl"><br> + ربما تسألت ما هي <strong>this</strong>. هي كلمة من الكلمات المحجوزة للغة جافاسكريبت.<br> + تشير إلى الكائن الحالي الذي تم كتابة التعليمات البرمجية داخله — في هذه الحالة هي تعادل person. فلماذا لا نستخدم person بدلا من ذلك؟<br> + كما سترى في <a href="/ar/docs/Learn/JavaScript/Objects/Object-oriented_JS"> جافاسكريبت - البرمجة غرضية التوجه للمبتدئين</a> عندما نبدأ بانشاء constructors، ... الخ، this مفيدة جداً — لانها ستضمن دائما أن تستخدم القيم الصحيحة عندما يتغير سياق العضو.<br> + ( على سبيل المثال عند وجود حالتين مختلفتين للكائن person بأسماء مختلفة، سوف ترغب في التعامل مع ال name الموجودة في كل منهما عن طريق الوظيفة ()greeting ).</p> + +<p dir="rtl">ولتوضيح ما نعنيه مع زوج من الكائنات person1 و person2 :</p> + +<pre class="brush: js">var person1 = { + name : 'Chris', + greeting: function() { + alert('Hi! I\'m ' + this.name + '.'); + } +} + +var person2 = { + name : 'Brian', + greeting: function() { + alert('Hi! I\'m ' + this.name + '.'); + } +}</pre> + +<p dir="rtl">في هذه الحالة، الوظيفة ()greeting الخاصة بالكائن person1، ستظهر ".<strong>Hi! I'm Chris</strong>".<br> + فيما الوظيفة ()greeting الخاصة بالكائن person2، ستقوم باظهار ".<strong>Hi! I'm Brian</strong>".<br> + على الرغم من ان التعليمات البرمجية للوظيفة greeting هي نفسها في كلا الحالتين. وكما قلنا في وقت سابق، <strong>this</strong> تساوي الكائن داخل التعليمات البرمجية — هي ليست مفيدة بشكل كبير خصوصا عند الكتابة خارج ال object literals، لكنها مفيدة جدا عندما تريد توليد كائن حيوي (على سبيل المثال باستخدام ال constructors). سوف تتضح لك الامور في وقت لاحق.</p> + +<h2 dir="rtl" id="استخدمنا_الكائنات_طوال_المرحلة">استخدمنا الكائنات طوال المرحلة</h2> + +<p dir="rtl">من خلال الأمثلة السابقة، لربما فكرت بأن نقطة الترميز التي استخدمناها مؤلوفة جدا. هذا لأننا استخدمناها تقريبا في جميع المراحل السابقة، في كل مرة كنا نعمل من خلال مثال يستخدم اما built-in browser API او JavaScript object، استخدمنا الكائنات، نظراً لأن هذه الميزات تم بناؤها باستخدام نفس النوع من ال object structures مثل ما راينا هنا،<br> + وإن كانت أكثر تعقيدا من الأمثلة الخاصة بنا.</p> + +<p dir="rtl">عند استخدامك لوظائف السلاسل النصية string methods، كهذه :</p> + +<pre class="brush: js">myString.split(',');</pre> + +<p dir="rtl">فقد استخدمت وظيفة متاحة في مثيل الفئة <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code>. في كل مرة تقوم فيها بإنشاء سلسلة نصية في التعليمات البرمجية الخاصة بك، بشكل اوتوماتيكي يتم انشاء هذه السلسلة النصية ك instance (مثيل) من String، وبالتالي سيصبح متاح لها العديد من ال methods/properties الخاصة بال String.</p> + +<p dir="rtl"><br> + عندما تصل الى document object model باستخدام سطور كهذه :</p> + +<pre class="brush: js">var myDiv = document.createElement('div'); +var myVideo = document.querySelector('video');</pre> + +<p dir="rtl">فقد استخدمت وظيفة متاحة في مثيل الفئة <code><a href="/en-US/docs/Web/API/Document">Document</a></code>. في كل مرة تحمل فيها صفحة الويب، يتم إنشاء instance (مثيل) من الوثيقة، تسمى <code>document</code>، والتي تمثل بنية الصفحة كاملة، والمحتوى، وغيرها من الميزات مثل عنوان URL الخاص بها. وهذا يعني أن لديها العديد من ال methods/properties المتاحة لها.</p> + +<p dir="rtl">وينطبق الأمر نفسه على اي من (كائنات <span class="short_text" id="result_box" lang="ar"><span class="alt-edited">برمجة</span></span> <span class="short_text" id="result_box" lang="ar"><span class="alt-edited">واجهة التطبيقات</span></span> المدمجة built-in object/API) الاخرى قد تمت باستخدام — <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math">Math</a></code>, etc.</p> + +<p dir="rtl">لاحظ ان الكائنات المدمجة Objects/APIs لا تقوم دائما بانشاء object instances (مثيلات الكائن) اوتوماتيكيا. وكمثال على ذلك، <a href="/en-US/docs/Web/API/Notifications_API">Notifications API</a> — التي تسمح للمتصفحات الحديثة باطلاق system notifications - يتطلب منك إنشاء مثيل object instance جديد باستخدام ال constructor لكل اشعار تريد اطلاقه.</p> + +<p dir="rtl">قم بادخال التعليمة التالية في console الجافاسكريبت الخاص بك :</p> + +<pre class="brush: js">var myNotification = new Notification('Hello!');</pre> + +<p dir="rtl">سوف نبحث في ال constructor في مقال لاحق.</p> + +<div class="note" dir="rtl"> +<p><strong>ملاحظة</strong>: من المفيد أن نفكر في طريقة تواصل الكائنات على شكل رسائل ممررة. — عندما يكون الكائن بحاجة لأداء بعض العمل في كثير من الأحيان سوف يرسل رسالة إلى كائن آخر عن طريق احدى وظائفه،<br> + وينتظر الرد، والذي يعرف بالقيمة المرجعة.</p> +</div> + +<h2 dir="rtl" id="ملخص">ملخص</h2> + +<p dir="rtl">تهانينا، لقد وصلت إلى نهاية الجزء الخاص بكائنات الجافاسكريبت الأولىية — وينبغي الآن ان تكون لديك فكرة جيدة عن كيفية العمل مع الكائنات في الجافا سكريبت بما في ذلك إنشاء الكائنات البسيطة الخاصة بك. وينبغي أن تدرك أيضا أن الكائنات مفيدة جداً كهياكل لتخزين البيانات والوظائف الخاصة بها. — إذا حاولت جعل كافة الخصائص والوظائف في الكائن person كمتغيرات ووظائف مستقلة، سيكون امر غير فعال ومخيب للامال، بحيث يمكن أن تتعرض لمخاطر اشتباك المتغيرات والوظائف التي لها نفس الأسماء.<br> + الكائنات تسمح لنا بالاحتفاظ بالمعلومات مؤمنة بأمان في حزمة خاصة بها، وتحفظها من الاذى.</p> + +<p dir="rtl"><strong>في المقال القادم سنبدأ بالنظر في البرمجة كائنية التوجه (OOP) ، وكيف يمكن استخدام هذه التقنية في جافا سكريبت.</strong></p> + +<p>{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}</p> +</div> diff --git a/files/ar/learn/javascript/objects/index.html b/files/ar/learn/javascript/objects/index.html new file mode 100644 index 0000000000..9eb705138c --- /dev/null +++ b/files/ar/learn/javascript/objects/index.html @@ -0,0 +1,53 @@ +--- +title: تقديم JavaScript objects +slug: Learn/JavaScript/Objects +tags: + - Article + - Assessment + - Beginner + - CodingScripting + - Guide + - JavaScript + - Learn + - NeedsTranslation + - Objects + - TopicStub + - Tutorial +translation_of: Learn/JavaScript/Objects +--- +<div>{{LearnSidebar}}</div> + +<p class="summary">في JavaScript ، معظم الأشياء هي كائنات ، من ميزات JavaScript الأساسية مثل السلاسل والمصفوفات إلى واجهات برمجة التطبيقات للمتصفح المبنية أعلى جافا سكريبت. يمكنك حتى إنشاء الكائنات الخاصة بك لتغليف الوظائف والمتغيرات ذات الصلة إلى حزم فعالة ، وتكون بمثابة حاويات بيانات مفيدة. إن طبيعة جافا سكريبت الموجهة للكائنات مهمة لفهم ما إذا كنت ترغب في مواصلة معرفتك باللغة ، لذلك قمنا بتوفير هذه الوحدة لمساعدتك. هنا نقوم بتدريس نظرية وجوه وبناء الجملة بالتفصيل ، ثم ننظر في كيفية إنشاء الأشياء الخاصة بك.</p> + +<p>المتطلبات الأساسية<br> + قبل البدء في هذه الوحدة ، يجب أن يكون لديك بعض الإلمام بـ HTML و CSS. يُنصح بالعمل من خلال مقدمة HTML ومقدمة إلى وحدات CSS قبل البدء في JavaScript.</p> + +<p>يجب أيضًا أن يكون لديك بعض الإلمام بأساسيات JavaScript قبل النظر إلى كائنات JavaScript بالتفصيل. قبل محاولة هذه الوحدة ، اعمل من خلال الخطوات الأولى لجافا سكريبت وكتل JavaScript</p> + +<p> </p> + +<div class="note">ملاحظة: إذا كنت تعمل على جهاز كمبيوتر / جهاز لوحي / جهاز آخر لا تملك فيه القدرة على إنشاء ملفاتك الخاصة ، يمكنك تجربة (معظم) أمثلة التعليمات البرمجية في برنامج ترميز عبر الإنترنت مثل JSBin أو Thimble</div> + +<p> </p> + +<div class="note"> </div> + +<blockquote> +<p id="Guides">خطوط إرشاد<br> + أساسيات الكائن<br> + في المقالة الأولى التي تبحث في كائنات JavaScript ، سننظر في بنية كائن جافا سكريبت الأساسية ، ونعاود زيارة بعض ميزات جافا سكريبت التي رأيناها سابقًا في الدورة التدريبية ، مع التأكيد على حقيقة أن العديد من الميزات التي تعاملت معها بالفعل هي في الواقع الأشياء.<br> + جافا سكريبت وجوه المنحى للمبتدئين<br> + مع وضع الأساسيات ، سنركز الآن على JavaScript (Object-oriented JavaScript) (OOJS) - تقدم هذه المقالة عرضًا أساسيًا لنظرية البرمجة الشيئية (OOP) ، ثم تستكشف كيفية محاكاة جافا سكريبت لفئات الكائن عن طريق وظائف منشئ ، كيفية إنشاء مثيلات الكائن.<br> + نماذج الكائن<br> + النماذج الأولية هي الآلية التي ترث بها كائنات JavaScript عناصر من بعضها البعض ، وتعمل بشكل مختلف مع آليات الوراثة في لغات البرمجة الكلاسيكية الموجهة للكائنات. في هذه المقالة ، نستكشف هذا الاختلاف ، ونشرح كيفية عمل سلاسل النموذج الأولي ، وننظر في كيفية استخدام خاصية النموذج الأولي لإضافة أساليب إلى المنشئات الموجودة.<br> + وراثة في جافا سكريبت<br> + مع شرح معظم تفاصيل دموية OOJS الآن ، يوضح هذا المقال كيفية إنشاء فئات الكائن "التابعة" (المنشئات) التي ترث ميزات من الفئات "الأصل" الخاصة بهم. بالإضافة إلى ذلك ، نقدم بعض النصائح حول متى وأين قد تستخدم OOJS.<br> + التعامل مع بيانات JSON<br> + يعد ترميز كائن جافا سكريبت (JSON) تنسيقًا قياسيًا لتمثيل البيانات المنظمة مثل كائنات جافا سكريبت ، والتي تستخدم عادة لتمثيل ونقل البيانات على مواقع الويب (أي إرسال بعض البيانات من الخادم إلى العميل ، بحيث يمكن عرضها على الويب الصفحة). ستصادفه كثيرًا ، لذا في هذه المقالة نقدم لك كل ما تحتاجه للعمل مع JSON باستخدام JavaScript ، بما في ذلك الوصول إلى عناصر البيانات في كائن JSON وكتابة JSON الخاص بك.<br> + ممارسة بناء الكائن<br> + في المقالات السابقة ، نظرنا في جميع تفاصيل بنية وجوه جافا سكريبت الأساسية وتفاصيل التركيب ، مما يمنحك قاعدة صلبة للبدء منها. في هذا المقال ، نتعمق في تمرين عملي ، مما يمنحك المزيد من التدريب على بناء كائنات جافا سكريبت مخصصة ، والتي تنتج شيئًا ممتعًا وملونًا - بعض الكرات المرتدة الملونة.</p> +</blockquote> + +<p id="Assessments">تقييم<br> + إضافة ميزات إلى الكرات المرتدة التجريبية<br> + في هذا التقييم ، يتوقع منك استخدام الكرات المرتدة التجريبية من المقالة السابقة كنقطة بداية ، وإضافة بعض الميزات الجديدة والممتعة إليها.</p> diff --git a/files/ar/learn/javascript/objects/inheritance/index.html b/files/ar/learn/javascript/objects/inheritance/index.html new file mode 100644 index 0000000000..7dc1333c96 --- /dev/null +++ b/files/ar/learn/javascript/objects/inheritance/index.html @@ -0,0 +1,228 @@ +--- +title: الوراثة في جافاسكريبت +slug: Learn/JavaScript/Objects/Inheritance +translation_of: Learn/JavaScript/Objects/Inheritance +--- +<div dir="rtl">{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</div> + +<p class="summary" dir="rtl">مع معظم التفاصيل المثيرة في OOJS التي درسناها حتى الآن،سنتطرق في هذا الدرس لكيفية إنشاء طفل (child" object classes (constructors" الذي يرث الميزات من أبيه parent" classes". بالإضافة إلى ذلك، سنقدم بعض النصائح، حول متى وأين يجب عليك استخدام ال OOJS.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th dir="rtl" scope="row">المتطلبات الأساسية :</th> + <td dir="rtl">دراية لا بأس بها بخصوص الحاسوب، الإلمام بمبادئ وأساسيات الـ HTML وCSS وجافاسكريبت (راجع <a href="/en-US/docs/Learn/JavaScript/First_steps">First steps</a> and <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Building blocks</a>) وأساسيات بناء الكائنات في الجافاسكريبت OOJS (راجع <a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introduction to objects</a>).</td> + </tr> + <tr> + <th dir="rtl" scope="row">الهدف :</th> + <td dir="rtl">فهم كيفية تنفيذ الوراثة في جافا سكريبت.</td> + </tr> + </tbody> +</table> + +<h2 dir="rtl" id="الوراثة_النمودجية_-_Prototypal_inheritance">الوراثة النمودجية - Prototypal inheritance</h2> + +<div style="font-size: 15; font-family: 'tahoma';"> +<p dir="rtl">لقد راينا حتى الآن بعض عمليات الوراثة — وراينا كيف تعمل الـ prototype chains، وكيف يتم توارث الاعضاء صعودا في السلسلة، ولكن معظمها اقتصر على الدوال المدمجة في المتصفح (built-in browser functions). الان، سنرى كيف يمكننا إنشاء كائن يرث من كائن آخر في جافا سكريبت؟</p> + +<p dir="rtl">كما ذكرنا في وقت سابق من هذه الدورة التدريبية، بعض الاشخاص يعتقدون أن جافاسكريبت ليست لغة كائنية حقيقية. في لغات "OO الكلاسيكية"، حيث يجب تعريف class objects من نوع ما، بعد ذلك يمكنك ببساطة تعريف الكلاس الذي سترث منه الكلاسات الأخرى (شاهد بعض الامثلة البسيطة بخصوص الوراثة في لغة <a href="http://www.tutorialspoint.com/cplusplus/cpp_inheritance.htm">C++ inheritance</a>). الجافا سكريبت تستخدم نظام مختلف — نظام <strong>الربط</strong> بين الكائنات — في الجافسكريبت لا يتم نسخ الوظائف الموروثة على الكائنات التي تقوم بالوراثة، بدلا من ذالك يتم عمل <strong>رابط</strong> بينها — الوظائف التي ترث <strong>مرتبطة</strong> عن طريق ال prototype chain (غالباً ما يشار لها بال <strong>prototypal inheritance</strong>).</p> + +<p dir="rtl">دعونا نستكشف كيفية القيام بذلك مع مثال ملموس.</p> + +<h2 dir="rtl" id="الشروع_في_العمل">الشروع في العمل</h2> + +<p dir="rtl">اولا وقبل كل شئ، قم بعمل نسخة من الملف الخاص بنا <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-start.html">oojs-class-inheritance-start.html</a> (او شاهد <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-start.html">running live</a>). ستجد داخله نفس مثال <code>Person()</code> constructor الذي استخدمناه طوال هذه الدورة التدريبية مع اختلاف طفيف — لقد قمنا بتعريف الخصائص فقط، داخل ال constructor:</p> + +<pre class="brush: js">function Person(first, last, age, gender, interests) { + this.name = { + first, + last + }; + this.age = age; + this.gender = gender; + this.interests = interests; +};</pre> + +<p dir="rtl">وكافة ال method معرفة كـ constructor's prototype ، على سبيل المثال:</p> + +<pre class="brush: js">Person.prototype.greeting = function() { + alert('Hi! I\'m ' + this.name.first + '.'); +};</pre> + +<div class="note"> +<p dir="rtl"><strong>ملحوظة : </strong>في شفرة المصدر سترى ايضا الوظائف <code>()bio </code>و <code>()farewell</code> معرفة . في وقت لاحق سترى كيف يمكن أن تكون موروثة من قبل منشئات-constructors آخرى.</p> +</div> + +<p dir="rtl">سنقوم بإنشاء <code>Teacher</code> class، مثل الذي قمنا بتوصيفه في تعريف object-oriented definition الخاصة بنا —والذي سيرث كافة الأعضاء من ال <code>Person</code>، ولكن سيشتمل أيضا على:</p> + +<ol> + <li>خاصية جديدة، <code>subject</code> — والتي ستحتوي على المادة التي يدرسها المدرس.</li> + <li>وعلى الوظيفة <code>greeting()</code> محدثة، والتي تبدو أكثر رسمية من الوظيفة <code>greeting()</code> القياسية —<br> + وهي اكثر ملائمة مع المدرس الذي يقوم بتدريس بعض الطلاب في المدرسة.</li> +</ol> + +<h2 dir="rtl" id="تعريف_ال_Teacher()_constructor_function">تعريف ال Teacher() constructor function</h2> + +<p dir="rtl">أول شيء يتعين علينا القيام به هو إنشاء <code>Teacher() </code>constructor — اضف ما يلي أدناه في التعليمات البرمجية خاصتك:</p> + +<pre class="brush: js">function Teacher(first, last, age, gender, interests, subject) { + Person.call(this, first, last, age, gender, interests); + + this.subject = subject; +}</pre> + +<p dir="rtl">تبدو هذه مشابهة لل Person constructor في نواح كثيرة، ولكن هناك شيء غريب والذي لم نره من قبل — الدالة<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call"> ()</a></code><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call">call</a></code> . هذه الدالة تسمح لك باستدعاء دالة اخرى معرفة في مكان آخر، ولكن في السياق الحالي، البراميتر الاول لتحديد قيمة <code>this</code>، اي هذا الذي نريد استخدامه عند تشغيل الدالة، والبرامترات الاخرى لتحديد البرامترات التي يجب ان تمرر للدالة عند تشغيلها.</p> + +<div class="note" dir="rtl"> +<p><strong>ملاحظة</strong>: في هذه الحالة سنقوم بتحديد الخصائص الموروثة عندما سنقوم بانشاء object instance، لكن لاحظ أنك ستحتاج إلى تحديدها كباراميترات في ال constructor حتى لو كان ال instance لا يتطلب ان تكون محددة كبارامترات.</p> +</div> + +<p dir="rtl">في هذه الحالة، وعلى نحو فعال قمنا بتشغيل ال Person() constructor function داخل ال Teacher() constructor function (انظر اعلاه). ما نتج عنه نفس الخصائص المعرفة داخل ()Teacher ولكن باستخدام قيم البرامترات التي تم تمريرها إلى ()Teacher وليس الى ()Person (ببساطة قمنا بتمرير this الى ()call وهذا يعني أن this داخل ()cal ستشير الى Teacher() function).</p> + +<p dir="rtl">السطر الأخير داخل ال constructor يعرف الخاصية subject الجديدة وهي خاصة ب ()Teacher فقط.</p> + +<p dir="rtl">كملاحظة، بإمكاننا ببساطة القيام بذلك على هذا النحو :</p> + +<pre class="brush: js">function Teacher(first, last, age, gender, interests, subject) { + this.name = { + first, + last + }; + this.age = age; + this.gender = gender; + this.interests = interests; + this.subject = subject; +}</pre> + +<p dir="rtl">ولكن هذا مجرد إعادة تحديد الخصائص من جديد، و ()Teacher لا يرثها من ال ()Person، لذا لا فائدة لما نحاول القيام به. لانه سيأخذ المزيد من السطور في التعليمات البرمجية لا اكثر.</p> + +<h2 dir="rtl" id="إعداد_Teacher()_prototype_ومرجع_ال_constructor">إعداد Teacher() prototype ومرجع ال constructor</h2> + +<p dir="rtl">كل شيء جيد حتى الآن، ولكن لدينا مشكلة. قمنا بتعيين constructor جديد، وبشكل افتراضي يحتوي على الخاصية prototype فارغة. ونحن بحاجة لجعل ()Teacher يرث الوظائف المعرفة في ال Person() prototype. فكيف نفعل ذلك؟</p> + +<p dir="rtl">أضف السطر التالي اسفل التعليمة البرمجية الخاصة بك:</p> + +<pre class="brush: js">Teacher.prototype = Object.create(Person.prototype);</pre> + +<p dir="rtl">وهنا يأتي دور الوظيفة<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create"> ()</a></code><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">create</a></code> للإنقاذ مرة أخرى — في هذه الحالة استخدمناها لإنشاء قيمة جديدة للخاصية prototype (وهي في حد ذاتها كائن يحتوي على خصائص ووظائف) مع prototype يساوي Person.prototype، وتعيينها كقيمة ل Teacher.prototype، وهذا يعني أن Teacher.prototype الآن سوف يرث كل الوظائف الموجودة في ال Person.prototype.</p> + +<p dir="rtl">نحن بحاجة إلى فعل شيئا آخر قبل أن نكمل — constructor الخاصية prototype ل ()Teacher<br> + هو الان على شكل ()Person، بسبب الطريقة التي ورثناها منه (لمزيد من المعلومات حول هذا <a href="https://stackoverflow.com/questions/8453887/why-is-it-necessary-to-set-the-prototype-constructor">Stack Overflow post</a>) — حاول حفظ التعليمات البرمجية الخاصة بك، واعد تحميل الصفحة من المتصفح، وادخل هذا في console الجافاسكريبت للتحقق:</p> + +<pre class="brush: js">Teacher.prototype.constructor</pre> + +<p dir="rtl">وهذا يمكن أن يسبب مشكلة، لذلك نحن بحاجة لتصحيح هذا الوضع، يمكنك القيام بذلك بالرجوع إلى التعليمات البرمجية الخاصة بك وإضافة السطر التالي في الجزء السفلي:</p> + +<pre class="brush: js">Teacher.prototype.constructor = Teacher;</pre> + +<p dir="rtl">الآن إذا قمت بحفظ وتحديث، وإدخال Teacher.prototype.constructor سيتم إرجاع ()Teacher، كما هو مطلوب.</p> + +<h2 dir="rtl" id="منح_()Teacher_الوظيفة_()greeting_الجديدة">منح ()Teacher الوظيفة ()greeting الجديدة</h2> + +<p dir="rtl">لانهاء الكود الخاص بنا، سنحتاج إلى تعريف الوظيفة الجديدة ()greeting في Teacher() constructor.</p> + +<p dir="rtl">أسهل طريقة للقيام بذلك، هو تعريفها على Teacher() prototype — اضف ما يلي في الجزء السفلي من التعليمات البرمجية الخاصة بك:</p> + +<pre class="brush: js">Teacher.prototype.greeting = function() { + var prefix; + + if(this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') { + prefix = 'Mr.'; + } else if(this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') { + prefix = 'Mrs.'; + } else { + prefix = 'Mx.'; + } + + alert('Hello. My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.'); +};</pre> + +<p dir="rtl">تحية المدرس هذه (alert)، يستخدم فيها أيضا الاسم prefix المناسب لجنسهم، بناءا على عبارة شرطية.</p> + +<h2 dir="rtl" id="تجربة_المثال">تجربة المثال</h2> + +<p dir="rtl">لقد ادخلت الآن كافة التعليمات البرمجية، حاول انشاء object instance من ()Teacher، عن طريق وضع ما يلي في الجزء السفلي لجافا سكريبت الخاصة بك :</p> + +<pre class="brush: js">var teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');</pre> + +<p dir="rtl">الآن حفظ وتحديث، وحاول الوصول إلى خصائص ووظائف الكائن teacher1 الجديد الخاص بك، على سبيل المثال:</p> + +<pre class="brush: js">teacher1.name.first; +teacher1.interests[0]; +teacher1.bio(); +teacher1.subject; +teacher1.greeting();</pre> + +<p dir="rtl">ستعمل جميعها بشكل جيد، الثلاثة الأولى ستصل إلى الأعضاء التي تم وراثتها من Person() constructor (class العام فيما الاثنان المتبقيان سيصلان إلى الأعضاء الموجودة في (Teacher() constructor (class.</p> + +<div class="note" dir="rtl"> +<p><strong>ملاحظة</strong> : إذا واجهتك مشكلة في الحصول على هذا العمل، قارن التعليمات البرمجية الخاصة بك مع خاصتنا <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-finished.html">finished version</a> (شاهد <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-finished.html">running live</a> ).</p> +</div> + +<p dir="rtl">التقنية التي قمنا بتغطيتها هنا ليست الطريقة الوحيدة لإنشاء كلاسات موروثة في جافا سكريبت، ولكنها تعمل بشكل جيد، وتعطيك فكرة جيدة عن كيفية تنفيذ الوراثة في جافا سكريبت.</p> + +<p dir="rtl">قد يهمك ايضا الاطلاع على بعض المستجدات {{glossary("ECMAScript")}} بخصوص المميزات الجديدة التي تسمح لنا بالقيام بوراثة أكثر نظافة في جافا سكريبت (شاهد <a href="/en-US/docs/Web/JavaScript/Reference/Classes">Classes</a>). ونحن لم نقم بتغطيتها هنا، كما لم يتم حتى الآن اعتمادها على نطاق واسع جداً عبر المتصفحات. كل التعليمات البرمجية الأخرى التي ناقشناها في هذه المجموعة من المقالات مدعومة بقدر ما، باستثناء IE9 وإلاصدارات السابقة، هناك طرق لتحقيق الدعم لما سبق.</p> + +<p dir="rtl">الطريقة الشائعة هي استخدام مكتبة جافا سكريبت — معظم الخيارات الشائعة تحتوي على مجموعة سهلة من الوظائف المتاحة لتنفيذ الوراثة بسهولة وسرعة. <a href="http://coffeescript.org/#classes">CoffeeScript</a> على سبيل المثال، توفر class ،extends،... الخ.</p> + +<h2 dir="rtl" id="اختبر_قدراتك">اختبر قدراتك</h2> + +<p dir="rtl">في القسم النظري الخاص بال <a href="/ar/docs/Learn/JavaScript/Objects/Object-oriented_JS#البرمجة_الكائنية_(أو_البرمجة_غرضية_التوجه)">OOP theory section</a>، أدرجنا أيضا Student class كمفهوم، والذي يرث كافة ميزات ال Person، ويحتوي على الوظيفة ()greeting بتحية مختلفة للشخص، وتحيته أكثر رسمية بكثير من تحية المدرس. الق نظرة على ما يشبه تحية الطالب في هذا القسم، وحاول تنفيذ Student() constructor خاص بك، على أن يرث كل ميزات ال ()Person، وقم بتنفيذ وظيفة ()greeting مختلفة.</p> + +<div class="note" dir="rtl"> +<p><strong>ملاحظة</strong> : إذا واجهتك مشكلة في الحصول على هذا العمل، قارن التعليمات البرمجية الخاصة بك مع خاصتنا <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-student.html">finished version</a> (شاهد ايضا <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-student.html">running live</a>).</p> +</div> + +<h2 id="Object_member_summary">Object member summary</h2> + +<p dir="rtl">تلخيص، لديك ثلاثة أنواع من property/method لتهتم بشانهم.</p> + +<ol> + <li>تلك المعرفة داخل ال constructor function والتي تمرر لل object instances. هذه سهلة إلى حد ما، في التعليمات البرمجية الخاصة بك، هناك أعضاء معرفة داخل ال constructor تستخدم نوع السطر this.x = x في built in browser code وهي متاحة فقط للأعضاء في object instances (عادة ما يتم إنشاؤها من خلال استدعاء ال constructor باستخدام الكلمة المحجوزة new مثل var myInstance = new <span dir="ltr">myConstructor()<span>)</span></span></li> + <li>تلك التي تم تحديدها مباشرة على constructor نفسها، وهي متاحة فقط في ال constructor.<br> + وهذه عادة متوفرة فقط في ال built-in browser objects,<br> + المعترف بها حاليا بالسلاسل مباشرة على ال constructor،<br> + لا على ال instance. على سبيل المثال <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a></code>.</li> + <li> + <p>تلك المحددة في constructor ال prototype، والموروثة من جميع ال instances<br> + ووراثة فئات الكائن. وتشمل اي عضو معرف على الخاصية Constructor's prototype property<br> + (مثلا ()myConstructor.prototype.x).</p> + </li> +</ol> + +<p dir="rtl">إذا لم تتمكن من استعاب هذا، فلا تقلق فانت حتى الآن لا تزال تتعلم، وسوف تستوعبها اكثر مع الممارسة.</p> + +<h2 dir="rtl" id="متى_تستخدم_الوراثة_في_جافا_سكريبت؟">متى تستخدم الوراثة في جافا سكريبت؟</h2> + +<p dir="rtl">على الارجح بعد هذه المادة الأخيرة، ستقول "يا الهي، هذا معقد"، حسنا، انت على حق، ال prototypes والوراثة تمثل بعض اهم الجوانب الأكثر تعقيداً في جافا سكريبت، لكن قوة ومرونة الجافا سكريبت تاتي من تركيبة الكائن والوراثة ومن المفيد فهم كيف تعمل.</p> + +<p dir="rtl">بطريقة ما، فانت تستخدم الوراثة طوال الوقت، كلما استخدمت الميزات المختلفة ل Web API (واجهة برمجة تطبيقات الويب) او الخصائص والوظائف المعرفة في كائنات المتصفح المدمجة (built-in browser) التي تقوم باستدعائها على السلاسل النصية الخاصة بك، او على المصفوفات...الخ، بشكل فعلي، فانت تستخدم الوراثة.</p> + +<p dir="rtl">بالنسبة لاستخدام الوراثة في التعليمات البرمجية الخاصة بك، ربما لن تحتاج لاستخدامها في كثير من الأحيان، لا سيما وانت مبتدئ فيها، او لديك مشاريع صغيرة. استخدام الكائنات والوراثة في هذه الحالة، سيكون مضيعة للوقت، وانت لست في حاجة إليها. ولكن كان تكون التعليمات البرمجية الخاصة بك اكبر وقابلة للتمدد، فأنت على الأرجح ستحتاجها بشكل كبير، إذا بدأت في إنشاء عدد من الكائنات، ووجدت ان لها خصائص مماثلة، عندها، قم بإنشاء نوع الكائن عام يحتوي على كافة الوظائف المشتركة ووراثة تلك المشتركة في نوع الكائنات الاكثر تخصصا، ما سيجعل هذ العمل مفيد ومريح.</p> + +<div class="note" dir="rtl"> +<p>ملاحظة: بسبب طريقة عمل الجافاسكريبت مع ال prototype chain ...الخ، غالباً ما تسمى مشاركة الوظائف بين الكائنات ب delegation (التفويض)، الكائنات المتخصصة تفوض هذه الوظائف إلى نوع الكائن العام. وربما هذا هو الوصف الاكثر دقة لوصف الوراثة، كما لا يتم نسخ الوظائف "الموروثة" على الكائنات التي تقوم "بالوراثة". بدلا من ذلك يتم عمل رابط بينها، لذا فالوظائف الموروثة لاتزال في الكائن العام.</p> +</div> + +<p dir="rtl">عند استخدام الوراثة، ينصح ان لا يكون لديك عدة مستويات من الوراثة، وتقوم بتتبع دقيق حيث يمكنك تحديد الخصائص والوظائف الخاصة بك. من الممكن البدء بكتابة التعليمات البرمجية والقيام بتعديل prototypes الكائنات المدمجة في المتصفح مؤقتاً، ولكن يجب أن لا تفعل ذلك إلا إذا كان لديك سبب وجيه حقا. والكثير من الوراثة يمكن أن يؤدي إلى ارتباكات لا نهاية لها، وآلام لا نهاية لها عند محاولة تصحيح هذه التعليمات البرمجية.</p> + +<p dir="rtl">في نهاية المطاف، الكائنات ليست سوى شكل آخر من أشكال إعادة استخدام التعليمات البرمجية، مثل الدوال والحلقات...الخ، مع أدوار محددة ومزايا خاصة بها. إذا كنت تقوم بإنشاء مجموعة من المتغيرات والمهام ذات الصلة، وتريد أن تجعلها جميعا معا محزمة بدقة وبعيدة عن مخاطر الاشتباك، فالكائن هو الحل. الكائنات أيضا مفيدة جداً عندما تريد تمرير مجموعة من البيانات من مكان إلى آخر. كل هذه الأمور لا يمكن تحقيقها بدون استخدام ال constructors أو الوراثة. إذا كنت بحاجة إلى instance واحد فقط من الكائن، فمن الافضل استخدام object literal، وبالتأكيد فلن تحتاج للوراثة.</p> + +<h2 dir="rtl" id="خلاصة">خلاصة</h2> + +<p dir="rtl"> غطت هذه المادة ما تبقى من نظرية ال OOJS الأساسية، وتركيبة الكائن الاساسية، من خلال هذه المعطيات فعلى الارجح انك اصبحت اكثر قدرة على فهم كائن الجافاسكريبت وأساسيات ال OOP، وايضا ال prototypes والميراث النمودجي (prototypal inheritance)، وكيفية إنشاء كلاسات (اي ما يعادل ال constructors في جافاسكريبت) وال object instances، واضافة ميزات الى الكلاسات، وانشاء كلاسات فرعية (subclasses)، التي ترث من الكلاسات الأخرى.</p> + +<p dir="rtl">في الدرس القادم سنلقي نظرة على كيفية التعامل مع ال (JavaScript Object Notation (JSON، وتبادل البيانات المشتركة باستخدام كائنات جافا سكريبت.</p> +</div> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="http://www.objectplayground.com/">ObjectPlayground.com</a> — A really useful interactive learning site for learning about objects.</li> + <li><a href="https://www.amazon.com/gp/product/193398869X/">Secrets of the JavaScript Ninja</a>, Chapter 6 — A good book on advanced JavaScript concepts and techniques, by John Resig and Bear Bibeault. Chapter 6 covers aspects of prototypes and inheritance really well; you can probably track down a print or online copy fairly easily.</li> + <li><a href="https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&%20object%20prototypes/README.md#you-dont-know-js-this--object-prototypes">You Don't Know JS: this & Object Prototypes</a> — Part of Kyle Simpson's excellent series of JavaScript manuals, Chapter 5 in particular looks at prototypes in much more detail than we do here. We've presented a simplified view in this series of articles aimed at beginners, whereas Kyle goes into great depth and provides a more complex but more accurate picture.</li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</p> diff --git a/files/ar/learn/javascript/objects/object-oriented_js/index.html b/files/ar/learn/javascript/objects/object-oriented_js/index.html new file mode 100644 index 0000000000..c57bbb13d5 --- /dev/null +++ b/files/ar/learn/javascript/objects/object-oriented_js/index.html @@ -0,0 +1,296 @@ +--- +title: جافاسكريبت - البرمجة غرضية التوجه للمبتدئين +slug: Learn/JavaScript/Objects/Object-oriented_JS +translation_of: Learn/JavaScript/Objects/Object-oriented_JS +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}</div> + +<p class="summary" dir="rtl">مع ما تعلمناه من أساسيات، سنركز الآن على جافاسكريبت غرضية التوجه (object oriented programming). او ما يعرف ب (OOP)، سنستعرض في هذه المقالة أساسيات البرمجة غرضية التوجه نظريا، ثم سنستكشف كيف أن الجافا سكريبت تظاهي الـ object classes المستخدمة في لغات البرمجة الأخرى (php مثلا) عن طريق الـ constructor functions، وأيضا كيفية إنشاء instances من الكائن (أو مثيل الكائن).</p> + +<table class="learn-box standard-table" style="height: 217px; width: 584px;"> + <tbody> + <tr> + <th dir="rtl" scope="row">المتطلبات الأساسية :</th> + <td> + <p dir="rtl">دراية لا باس بها بخصوص الحاسوب، الإلمام بمبادئ وأساسيات الـ HTML وCSS وjavascript (شاهد <a href="/en-US/docs/Learn/JavaScript/First_steps">First steps</a> و <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Building blocks</a>) وأساسيات بناء الـكائنات OOJS. (شاهد <a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introduction to objects</a>).</p> + </td> + </tr> + <tr> + <th dir="rtl" scope="row">الهدف :</th> + <td dir="rtl">فهم نظريا الـبرمجة غرضية التوجه (object-oriented programming)، وكيف أن كل شيء في الجافاسكريبت عبارة عن كائن (object) !.<br> + وأيضا كيفية إنشاء الـ constructors وobject instances.</td> + </tr> + </tbody> +</table> + +<h2 dir="rtl" id="البرمجة_الكائنية_(أو_البرمجة_غرضية_التوجه)">البرمجة الكائنية (أو البرمجة غرضية التوجه) </h2> + +<div style="font-size: 14px; font-family: 'tahoma';"> +<p dir="rtl">لنبدأ، دعونا نقوم بعرض نبذة بسيطة عن ماهي البرمجة غرضية التوجه ( Object-oriented programming ( OOP على مهل. نقول على مهل، لأن فهم واستيعاب البرمجة غرضية التوجه (OOP) على عجل سيكون امر غاية في التعقيد، كأن نعطيك العلاج الكامل الآن على الأرجح سيسبب لك خلطا أكثر مما سيساعدك. <br> + الفكرة الأساسية من البرمجة غرضية التوجه OOP هي أن نستخدم أشياءً من عالمنا الحقيقي ونحولها إلى كائنات ونقوم بتمثيلها داخل برامجنا، ونوفر وسائل سهلة للوصول إلى وظائفها، حتى نستفيد منها.</p> + +<p dir="rtl">يتكون الكائن من مجموعة من البيانات والتعليمات البرمجية المتصلة فيما بينها. والتي تمثل معلومات عن الشيء الذي نتعامل معه، والوظيفة أو السلوك الذي نريد منه أن يقوم به. بيانات الكائن في كثير من الأحيان تكون عبارة عن وظائف كثيرة يمكن تخزينها بدقة (أو تغليفها) داخل حزمة الكائن (object package). حزمة الكائن يمكن أن تمتلك اسما يشير إليها، وهو ما يسمى في بعض الأحيان ب namespace. ما يجعل من السهل إعادة هيكلتها أو الوصول إليها، كما يمكن أيضا استخدام الكائنات كمخازن للبيانات حتى يمكن إرسالها بسهولة عبر شبكة الاتصال.<br> + </p> + +<h3 dir="rtl" id="تعريف_الـ_object_template">تعريف الـ object template</h3> + +<p dir="rtl">دعونا ننظر في برنامج سهل يستعرض معلومات عن الطلاب والمعلمين في المدرسة.<br> + هنا سوف نبحث في نظرية البرمجة الغرضية التوجه OOP بشكل عام، وليس في سياق أي لغة برمجة معينة.</p> + +<p dir="rtl">اولا، دعونا نعود إلى الكائن Person الذي عملنا عليه في الدرس السابق <a href="/ar/docs/Learn/JavaScript/Objects/Basics">قسم اساسيات الكائن في جافاسكريبت</a>، والذي يحدد البيانات العامة والأداء الوظيفي للشخص. هناك الكثير من المواصفات التي يمكن أن يتصف بها اي شخص (عنوانه، الطول، حجم الحذاء، الحمض النووي للشخصية DNA، ورقم جواز السفر، مواصفات شخصية كثيرة...)، في المثال الذي عملنا عليه في الدرس السابق، ركزنا اهتمامنا فقط على عرض الاسم، والسن والجنس، والاهتمامات، نريد أيضا أن نكون قادرين على كتابة مقدمة قصيرة حول هؤلاء الاشخاص، على أساس هذه البيانات، وجعلهم يقولون مرحبا، وهذا ما يعرف بالتجريد abstraction.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13889/person-diagram.png" style="display: block; height: 219px; margin: 0px auto; width: 610px;"></p> + +<p dir="rtl">في بعض لغات البرمجة غرضية التوجه OOP الأخرى (PHP مثلا)، يعرف الكائن عامة بال class (جافا سكريبت تستخدم مصطلحات وآلية مختلفة، كما سنرى أدناه) - في الواقع هو ليس كائنا، بل هو القالب الذي يعرف خصائص الكائن وكيف ينبغي له أن يكون.</p> + +<h3 dir="rtl" id="إنشاء_كائنات_فعلية_-_Creating_actual_objects">إنشاء كائنات فعلية - Creating actual objects </h3> + +<p dir="rtl">من خلال الـ class، يمكنك إنشاء object instances — وهي الكائنات التي تحتوي على البيانات والوظائف المحددة في الـ class (وبالتالي هي مثيلة له). من خلال الـ class Person الخاص بنا، يمكننا الآن إنشاء بعض الأشخاص الفعليين :</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13883/MDN-Graphics-instantiation-2.png" style="display: block; height: 743px; margin: 0px auto; width: 700px;"></p> + +<p dir="rtl">عندما يتم إنشاء object instance من الـ class، ستبدأ الـ constructor function الخاصة بال class بإنشائه، تسمى عملية إنشاء الـ object instance من الـ class بال instantiation (إنشاء مثيل).<br> + أي أنَّ الـ object instance هو instantiated (مثيل) من الـ class.</p> + +<h3 dir="rtl" id="كلاسات_متخصصة_-_Specialist_classes">كلاسات متخصصة - Specialist classes</h3> + +<p dir="rtl">في هذه الحالة لسنا بحاجة للأشخاص بصفة عامة، سنستخدم الأساتذة والطلاب بصفة <strong>خاصة</strong>. في البرمجة غرضية التوجه OOP، يمكنك إنشاء كلاسات بناءً على كلاسات أخرى. مثلا كلاسات الأبناء child الجديدة يمكنها أن ترث البيانات والتعليمات البرمجية من الكلاس الأب parent.<br> + يمكنك إعادة استخدام وظيفة مشتركة بين جميع أنواع الكائنات بدلاً من الاضطرار إلى تكرار العملية عدة مرات، حيث يختلف الأداء الوظيفي من كلاس لآخر، يمكنك <strong>تخصيص</strong> ميزات معينة لكل منها حسب الحاجة.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13881/MDN-Graphics-inherited-3.png" style="display: block; height: 743px; margin: 0px auto; width: 700px;"></p> + +<p dir="rtl">وهذا مفيد حقاً – حيث يتشارك المعلمين والطلاب في الكثير من الخصوصيات المشتركة مثل الاسم ونوع الجنس، والعمر، سيكون من المفيد جدا تعريف تلك الخصوصيات المشتركة مرة واحدة فقط. يمكنك أيضا تعريف نفس تلك الخصوصيات كل على حدة في الكلاسات المختلفة، كما سيتم تعريف كل من هذه الخصوصيات في namespace مختلفة. على سبيل المثال، قد تكون تحية الطالب على هذا الشكل <code>( Yo, I'm [firstName]" ( <em>Hi, I'm Sam</em>"</code>، بينما قد يستخدم المعلم شيئا أكثر رسمية،<br> + مثل<code>Hello, my name is [Prefix] [lastName] and I teach [Subject]. " ) <em>Hello, My name is Mr Griffiths, and I teach Chemistry</em>)</code>.</p> + +<div class="note" dir="rtl"> +<p>ملاحظة : قدرة الكائنات المتعددة على تنفيذ نفس الوظائف تسمى <strong>polymorphism</strong> (تعدد الأشكال).</p> +</div> + +<p dir="rtl">يمكنك الآن إنشاء object instances من child classes. على سبيل المثال :</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13885/MDN-Graphics-instantiation-teacher-3.png" style="display: block; height: 743px; margin: 0px auto; width: 700px;"></p> + +<p dir="rtl">في باقي المقالة سنبدأ بإلقاء نظرة عملية على البرمجة غرضية التوجه OOP في جافا سكريبت.</p> + +<h2 dir="rtl" id="الـ_Constructors_والـ_object_instances">الـ Constructors والـ object instances</h2> + +<p dir="rtl">بعض الناس يقولون أن جافاسكريبت ليست لغة كائنية حقيقية، لأنها لا تستخدم الكلمة المحجوزة class لإنشاء الكلاسات مثل العديد من لغات البرمجة الغرضية التوجه OOP. بدلاً من ذلك، الجافاسكريبت تستخدم وظائف خاصة تسمى constructor functions لتعريف الكائنات وميزاتها. هذه الوظائف مفيدة جدا لأنك غالبا ما ستواجه حالات، حيث لا يمكنك معرفة عدد الكائنات التي ستقوم بإنشائها. وبالتالي ستوفر لك الـ constructors الوسائل اللاَّزمة لإنشاء العديد من الكائنات التي تحتاج إليها بطريقة فعالة، وربط البيانات والوظائف كما هو مطلوب.</p> + +<p dir="rtl">عندما يتم إنشاء object instance جديد من الـ constructor function، لا يتم نسخ كل الوظائف الى الكائن الجديد مثل الـ «classic OO languages». بدلاً من ذلك يتم تكوين رابط وظيفي بواسطة reference chain تسمى prototype chain (شاهد <a href="/ar/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a>). حتى هذا ليس تجسيدًا حقيقـيًّا، إذا توخينا الدقة، فجافاسكريبت تستخدم آلية مختلفة لتبادل الوظائف بين الكائنات.</p> + +<div class="note" dir="rtl"> +<p><strong>ملاحظة</strong> : عدم وجود الـ "classic OOP" ليس بالضرورة أمرا سيئاً، كما ذكر أعلاه، البرمجة الغرضية التوجه OOP معقدة للغاية، لكن للجافاسكريبت بعض الطرق اللطيفة للاستفادة من ميزات الـ OO دون الحاجة للتعمق كثيرا فيها.</p> +</div> + +<p dir="rtl">لنبدأ بإنشاء كلاسات عن طريق الـ constructors، وإنشاء object instances منها في جافاسكريبت.<br> + أولاً وقبل كل شيء، نود منك عمل نسخة من الملف التالي <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs.html">oojs.html</a> الذي سبق وأن عملنا عليه في الدرس السابق.</p> + +<h3 dir="rtl" id="مثال_سهل">مثال سهل</h3> + +<p dir="rtl">دعونا نبدأ بالنظر في كيفية تعريف شخص من خلال دالة عادية. أضف هذه الدالة أدناه إلى التعليمات البرمجية الموجودة لديك:</p> + +<pre class="brush: js" dir="rtl">function createNewPerson(name) +{ + var obj = {}; + obj.name = name; + obj.greeting = function () { + alert('Hi! I\'m ' + this.name + '.'); + } + return obj; +}</pre> + +<p dir="rtl">يمكنك الآن إنشاء Person جديد بواسطة استدعاء هذه الدالة، حاول إدخال الأسطر التالية في console الجافاسكريبت في المتصفح الخاص بك:</p> + +<pre class="brush: js" dir="rtl">var salva = createNewPerson('salva'); +salva.name; +salva.greeting();</pre> + +<p dir="rtl">يعمل بشكل جيد، ولكنه عمل متعب قليلا. إذا كنا نعرف أننا سننشئ كائنًـا، لماذا نحتاج إلى إنشاء كائن جديد فارغ ونعود إليه (عبر return)؟ من حسن الحظ، جافاسكريبت تزودنا باختصار مفيد على شكل constructor functions، دعونا الآن ننشئ واحدا !</p> + +<p dir="rtl">قم باستبدال الدالة السابقة بهذه :</p> + +<pre class="brush: js">function Person(name) +{ + this.name = name; + this.greeting = function() { + alert('Hi! I\'m ' + this.name + '.'); + }; +}</pre> + +<p dir="rtl">الـ constructor function هو نسخة الجافاسكريبت فيما يتعلق بال class.<br> + ستلاحظ أن لديها كافة الميزات التي تتوقعها في الدالة، على الرغم من أنها لا تقوم بإرجاع أي شيء، ولا تقوم بإنشاء كائن، لحد الآن هي مجرد تعريف للـخصائص <code>(properties)</code> والوظائف <code>(methods)</code>، سترى أيضا هذه الكلمة <code>this</code> المستخدمة هنا، فكرتها أنه كلما تم إنشاء أحد الـ object instances، فإن الـ object's name property سيساوي قيمة الـ name الممررة إلى الـ constructor call، والوظيفة () greeting ستستخدم قيمة name الممررة إلى الـ constructor call أيضا.</p> + +<p dir="rtl"><strong>الـ constructor call هو الذي يكون على هذا الشكل new Object(parameters) كما سنرى بعد قليل.</strong></p> + +<div class="note"> +<p dir="rtl"><strong>ملاحظة </strong>: عادة ما يبدأ اسم الـ constructor function بحرف كبير - يتم استخدام هذا التقليد حتى يسهل التعرف على الـ constructor functions في التعليمات البرمجية بسهولة.</p> +</div> + +<p dir="rtl">كيف يمكننا استدعاء الـ constructor لإنشاء بعض الكائنات؟</p> + +<p dir="rtl">أضف الأسطر التالية أدناه الى اسفل التعليمات البرمجية الخاص بك:</p> + +<pre class="brush: js">var person1 = new Person('Bob'); +var person2 = new Person('Sarah');</pre> + +<p dir="rtl">احفظ التعليمات البرمجية الخاصة بك واعد تحميل الصفحة، وحاول إدخال الأسطر التالية في حقل المدخلات الخاص بك (كل على حدة) :</p> + +<pre class="brush: js" dir="rtl">person1.name +person1.greeting() +person2.name +person2.greeting()</pre> + +<p dir="rtl">جميل! اصبح لدينا كائنان جديدان في الصفحة، تم تخزين كل منهما ضمن namespace مختلفين، للوصول إلى الخصائص والوظائف الخاصة بهما، عليك أن تبدأ بالاتصال اما مع person1 أو person2، هما الان مغلفين بدقة، وبالتالي سنضمن عدم تشابك الوظائف مع بعضها، لاحظ ان لديهم نفس الخاصية name ونفس الوظيفة () greeting، الا أن كل واحد منهما سيحصل على القيمة name التي تم تعيينها له. هذا واحد من الاسباب التي تعرفنا على اهمية <code>this</code>، حيث انها ستشير الى الكائن الخاص بها وليس لشئ اخر.</p> + +<p dir="rtl">دعونا ننظر في ال constructor calls مرة أخرى :</p> + +<pre class="brush: js">var person1 = new Person('Bob'); +var person2 = new Person('Sarah');</pre> + +<p dir="rtl">في كل حالة من الحالتين، يتم استخدام الكلمة المحجوزة <code>new</code> لاخبار المتصفح بأننا نريد إنشاء object instance جديد، متبوعة باسم الدالة و ال parameters المطلوبة بين الأقواس، ويتم تخزين النتيجة في متغير، وهي شبيهة جدا بكيفية استدعاء standard function، ويتم إنشاء كل instance وفقا لهذا التعريف:</p> + +<pre class="brush: js">function Person(name) { + this.name = name; + this.greeting = function() { + alert('Hi! I\'m ' + this.name + '.'); + }; +}</pre> + +<p dir="rtl">بعد أن يتم إنشاء الكائنات الجديدة، فعليا، ستحتوي المتغيرات person1 و person2 على الكائنات التالية على هذا النحو :</p> + +<pre class="brush: js">{ + name : 'Bob', + greeting : function() { + alert('Hi! I\'m ' + this.name + '.'); + } +} + +{ + name : 'Sarah', + greeting : function() { + alert('Hi! I\'m ' + this.name + '.'); + } +}</pre> + +<p dir="rtl">قلنا فعليا لأنه في الواقع الفعلي لا يزال يتم تعريف الوظائف في ال class، وليس في object instances، على عكس ال object literal كما راينا سابقا.</p> + +<h3 dir="rtl" id="انشاء_constructor">انشاء constructor</h3> + +<p dir="rtl">المثال الذي راينا اعلاه، كان مجرد مقدمة، دعونا الان ننشئ Person() constructor function. فعلي.</p> + +<p dir="rtl">قم بحذف التعليمات البرمجية التي قمت بإدراجها حتى الآن، واضف هذا ال constructor بدلا منه – هو بالضبط نفس المثال البسيط اعلاه من حيث المبدأ، مع القليل من التعقيد :</p> + +<pre class="brush: js">function Person(first, last, age, gender, interests) { + this.name = { + first, + last + }; + this.age = age; + this.gender = gender; + this.interests = interests; + this.bio = function() { + alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.'); + }; + this.greeting = function() { + alert('Hi! I\'m ' + this.name.first + '.'); + }; +};</pre> + +<p dir="rtl">الآن أضف ال constructor call التالي، لإنشاء object instance من ال constructor خاصتنا :</p> + +<pre class="brush: js">var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);</pre> + +<p dir="rtl">يمكنك الآن الوصول إلى الخصائص والوظائف مثلما فعلنا مع الكائن اعلاه :</p> + +<pre class="brush: js">person1['age'] +person1.interests[1] +person1.bio() +// etc.</pre> + +<div class="note" dir="rtl"> +<p><strong>ملاحظة</strong>: إذا كنت تواجه صعوبة في الحصول على هذا العمل، حاول مقارنة التعليمات البرمجية الخاصة بك مع التعليمات الخاصة بنا — see <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-finished.html">oojs-class-finished.html</a> (also <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-finished.html">see it running live</a>).</p> +</div> + +<h3 dir="rtl" id="امتحان_بسيط">امتحان بسيط</h3> + +<p dir="rtl">في هذا الامتحان البسيط وجب عليك إضافة بضعة أسطر اضافية الى الكائن Person خاصتك، ومحاولة جلب وإعداد الاعضاء من ناتج ال object instances.</p> + +<p dir="rtl">هناك مشكلتين بخصوص الوظيفة ()bio :<br> + أ- مخرجاتها ستكون دائما عبارة عن الضمير هو "He"، حتى وان كان الشخص انثى.<br> + ب- الوظيفة bio سترجع اثنين من الاهتمامات (interests) فقط، حتى وان تم تعيين أكثر من ذالك في مصفوفة الاهتمامات interests.<br> + يمكن العمل على حل هذه المشكلة داخل ال ?( class definition ( constructor.<br> + يمكنك وضع أي كود تريده داخل ال constructor (على الأرجح سوف تحتاج لبضع جمل شرطية "if..else if...else" وحلقة "for").<br> + مطلوب منك حل هذه المشكلة آخدا بعين الاعتبار نوع الجنس (ذكر/انثى). وايضا عدد الاهتمامات interests كان تكون 1 أو 2 أو أكثر من 2. </p> + +<div class="note" dir="rtl"> +<p><strong>ملاحظة </strong>: إذا واجهتك مشكلة، فقد قمنا بتوفير الاجابة، <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">answer inside our GitHub repo</a> (<a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">see it live</a>) — ننصح بالاعتماد على نفسك اولا !.</p> +</div> + +<h2 dir="rtl" id="طريقة_اخرى_لانشاء_ال_object_instances">طريقة اخرى لانشاء ال object instances</h2> + +<p dir="rtl">حتى الآن رأينا طريقتان مختلفتان لإنشاء ال object instance :</p> + +<ol dir="rtl"> + <li>باستخدام <a href="/ar/docs/Learn/JavaScript/Objects/Basics#أساسيات_الكائن"> الاعلان عن ال object literal</a> (الدرس السابق).</li> + <li>باستخدام constructor function (انظر أعلاه).</li> +</ol> + +<p dir="rtl">هذا منطقي, ولكن هناك طرق أخرى، نريد ان نجعلها مالوفة لديك في حالة مصادفتها في مكان ما على شبكة الويب.</p> + +<h3 dir="rtl" id="The_Object()_constructor">The Object() constructor</h3> + +<p dir="rtl">يمكنك استخدام ال <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object()</a></code> constructor لانشاء كائن جديد، نعم، حتى الكائنات العامة تحتوي على constructor والذي بدوره يولد كائنا فارغا.</p> + +<p dir="rtl">حاول ادخال السطر التالي في console المتصفح الخاص بك :</p> + +<pre class="brush: js" dir="rtl">var person1 = new Object();</pre> + +<p dir="rtl">سيقوم هذا بتخزين كائن فارغ في المتغير person1. يمكنك بعد ذالك اضافة الخصائص والوظائف لهدا الكائن،<br> + باستخدام نقطة الترميز او باستخدام اقواس الترميز، حسب الطلب. جرب هذا المثال :</p> + +<pre class="brush: js">person1.name = 'Chris'; +person1['age'] = 38; +person1.greeting = function() { + alert('Hi! I\'m ' + this.name + '.'); +}</pre> + +<p dir="rtl">يمكنك ايضا تمرير object literal الى ال Object() constructor ك parameter معبأة على شكل properties/methods. جربه بنفسك :</p> + +<pre class="brush: js">var person1 = new Object({ + name : 'Chris', + age : 38, + greeting : function() { + alert('Hi! I\'m ' + this.name + '.'); + } +});</pre> + +<h3 dir="rtl" id="باستخدام_الوظيفة_()create">باستخدام الوظيفة ()create</h3> + +<p dir="rtl">الجافاسكريبت لديها وظيفة مبنية مسبقا (built-in method) تسمى <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">()</a></code><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">create</a></code>, والتي تسمح لك بإنشاء object instance جديد استناداً إلى كائن موجود.</p> + +<p dir="rtl">جرب ادخال هذا السطر في console المتصفح الخاص بك :</p> + +<pre class="brush: js">var person2 = Object.create(person1);</pre> + +<p dir="rtl">والان جرب هذه :</p> + +<pre class="brush: js">person2.name +person2.greeting()</pre> + +<p dir="rtl">سترى أن person2 قد تم إنشاؤه استناداً إلى person1 — فاصبح يمتلك نفس الخصائص والوظائف المتاحة لل person1 وهذا مفيد جداً، حيث أنه سيسمح لك بإنشاء object instances جديد، دون الحاجة إلى تعريف ال constructor.<br> + الجانب السلبي هو أن ال <code>()create</code> غير مدعومة من قبل بعض المتصفحات، فيما يتعلق بالعودة ك constructors ( <span class="short_text" id="result_box" lang="ar"><span>IE8</span> وما قبله</span> لا يدعم هذه الوظيفة ) ، بالإضافة إلى ذلك يعتقد البعض أن ال constructors تمنح التعليمات البرمجية الخاصة بك مميزات اكثر. يمكنك إنشاء constructors خاصة بك في مكان واحد، ومن ثم إنشاء instances حسب الحاجة،</p> + +<p dir="rtl">ومع ذلك، إذا لم تكن قلقا جداً بشأن دعم المتصفحات القديمة حقاً، وتحتاج فقط لبضع نسخ من الكائن، فان انشاء constructor قد يكون مبالغة بالنسبة للتعليمات البرمجية الخاصة بك. الأمر متروك لك ولما تفضله. ببساطة بعض الناس يجدون ال <code>()create</code>. سهلة في الفهم والاستخدام.</p> + +<p dir="rtl">سوف نستكشف ال <code>()create</code> بمزيد من التفصيل في وقت لاحق.</p> + +<h2 dir="rtl" id="ملخص">ملخص</h2> + +<p dir="rtl">قدمت هذه المقالة طريقة مفصلة حول ال object-oriented نظريا، هذه ليست القصة بأكملها، ولكنها تعطيك فكرة عن ما نتعامل معه هنا. باﻹضافة إلى ذلك، فقد راينا الكيفية التي ترتبط بها جافا سكريبت، وكيف انها تختلف عن مفهوم ال "classic OOP"، راينا كذالك، كيفية تنفيذ ال الكلاسات classes في الجافاسكريبت باستخدام ال constructor functions، وطرق مختلفة لتوليد ال object instances.</p> +</div> + +<p dir="rtl"><strong>ان شاء الله في الدرس القادم سوف نستكشف prototypes الجافا سكريبت.</strong></p> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}</p> diff --git a/files/ar/learn/javascript/objects/object_prototypes/index.html b/files/ar/learn/javascript/objects/object_prototypes/index.html new file mode 100644 index 0000000000..1e91d18013 --- /dev/null +++ b/files/ar/learn/javascript/objects/object_prototypes/index.html @@ -0,0 +1,248 @@ +--- +title: ال Object prototypes +slug: Learn/JavaScript/Objects/Object_prototypes +translation_of: Learn/JavaScript/Objects/Object_prototypes +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}</div> + +<p class="summary" dir="rtl">ال Prototypes هي الآلية التي تعتمدها الجافاسكريبت للوراثة، بمعنى آخر، يمكننا من خلال ال Prototypes جعل كائن يرث مميزات كائن آخر. وهي تعمل بشكل مختلف عن مفهوم آلية الوراثة في اللغات الغرضية التوجة الكلاسيكية. في هذا الدرس سنكتشف هذا الاختلاف، وسنرى كيف تعمل ال prototype chains، وسنلقي نظرة حول كيفية إضافة وظيفة معينة لـ constructors موجودة عن طريق الخاصية prototype. </p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th dir="rtl" scope="row">المتطلبات الأساسية :</th> + <td dir="rtl">دراية لا بأس بها بخصوص الحاسوب، الإلمام بمبادئ وأساسيات الـ HTML وCSS وجافاسكريبت (راجع <a href="/en-US/docs/Learn/JavaScript/First_steps">First steps</a> and <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Building blocks</a>) وأساسيات بناء الكائنات في الجافاسكريبت OOJS (راجع <a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introduction to objects</a>).</td> + </tr> + <tr> + <th dir="rtl" scope="row">الهدف :</th> + <td dir="rtl">فهم جافاسكريبت object prototypes، وكيف تعمل ال prototype<strong> </strong> chains، وكيفية إضافة وظائف جديدة على الخاصية prototype.</td> + </tr> + </tbody> +</table> + +<h2 dir="rtl" id="الجافا_سكريبت_لغة_تعتمد_على_ال_prototype_؟">الجافا سكريبت لغة تعتمد على ال prototype ؟</h2> + +<div style="font-size: 15px; font-family: 'tahoma';"> +<p dir="rtl">غالبا ما توصف جافاسكريبت، على أنها لغة تعتمد على البروتوتايب (prototype-based language)، بمعنى، ان كل <strong><code>كائن</code></strong> في الجافاسكريبت يحتوي على <strong><code>الكائن</code></strong> <strong><code>prototype</code></strong>، الذي يرث خصائص ووظائف <strong><code>ال </code></strong> <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code>. الكائن <strong><code>prototype</code></strong> يمكنه أيضا أن يحتوي على <strong><code>كائن prototype</code></strong> خاص به، ويرث خصائصه ووظائفه ايضا، وهكذا ودواليك. يعرف هذا السلوك بال prototype chain (سلسلة النمودج). وهذا يشرح، كيف انه بإمكان كائن معين ان يصل لخصائص ووظائف مُعَرَّفة في كائن اخر.</p> + +<p dir="rtl">حسنا، حتى نكون أكثر دقة، الخصائص والوظائف مُعَرَّفة في الـ Objects' constructor functions وليس في الـ object instances (مثيلات الكائن).</p> + +<p dir="rtl">بالنسبة للبرمجة الكلاسيكية غرضية التوجه classic OOP، يتم تعريف الكلاسات، بعد أن يتم إنشاء object instances، ويتم نسخ كافة الخصائص والوظائف المعرفة في الكلاس فوق ال instance.<br> + في الجافاسكريبت، الأمر مختلف، حيث يتم تكوين رابط بين الـ object instance والـ constructor الخاص به. يمكن تشبيه الأمر بتكوين (حلقة في سلسلة ال <code>prototype</code>)، ويتم الوصول إلى الخصائص والوظائف من الـ constructor، من خلال التنقل صعودا في السلسلة. بمعنى اخر، سيبدأ مُفسِّر الجافاسكريبت بالبحث داخل النمادج <strong><code>prototypes،</code></strong> عن الخاصّية او الوظيفة المطلوبة، من اسفل سلسلة الوراثة، ويكمل بالبحث حتى يصل الى اعلاها.</p> + +<p dir="rtl">دعونا نلقي نظرة على هذا المثال ليصبح الأمر أكثر وضوحا.</p> + +<h2 dir="rtl" id="فهم_ال_prototype_objects">فهم ال prototype objects</h2> + +<p dir="rtl">لنَـعُد إلى المثال الذي انتهينا من كتابتة Person() constructor، قم بتحميل المثال التالي في المتصفح الخاص بك، إذا لم يكن لديك المثال الذي عملنا عليه في الدرس السابق استخدم المثال الخاص بنا <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">oojs-class-further-exercises.html</a> او (قم بنسخ <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">source code</a>).</p> + +<p dir="rtl">في هذا المثال قمنا بتعريف constructor function، كالتالي :</p> + +<pre class="brush: js">function Person(first, last, age, gender, interests) { + + // property and method definitions + this.frist = frist; + //etc.. +};</pre> + +<p dir="rtl">ثم قمنا بإنشاء object instance منه هكذا :</p> + +<pre class="brush: js">var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);</pre> + +<p dir="rtl">إذا قمت بكتابة "<strong>.</strong><code>person1</code>" في console الجافاسكريبت، ستلاحظ ان المتصفح يقوم بالاكمال التلقائي ويظهر اسماء الاعضاء الموجودة في هذا الكائن. </p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13853/object-available-members.png" style="display: block; margin: 0 auto;"></p> + +<p dir="rtl">في هذه القائمة، نرى الاعضاء المعرفة في ال Person() constructor، الذي يمثله ال <strong><code>person1</code></strong> وهذه الاعضاء هي <code>name, age, gender, interests, bio</code> و <code>greeting</code>. كما نرى ايضا بعض الأعضاء الآخرين مثل <code>watch ،valueOf</code>،...الخ. وهي معرفة في <code>prototype</code> ال Person() constructor، ال <code>prototype</code> الخاص بال Person() constructor هو ال <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code> نفسه.</p> + +<p dir="rtl">والرسم التبياني التالي يوضح لنا، كيفة عمل ال prototype chain.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13891/MDN-Graphics-person-person-object-2.png" style="display: block; height: 150px; margin: 0px auto; width: 700px;"></p> + +<p dir="rtl">فماذا سيحدث إذا قمنا باستدعاء وظيفة على ال <strong><code>person1</code></strong>، وهي احدى الوظائف المعرفة في ال Object؟. على سبيل المثال:</p> + +<pre class="brush: js">person1.valueOf()</pre> + +<p dir="rtl">ببساطة فهذه الوظيفة <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf">()</a></code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf">valueOf</a></code> مملوكة لل <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code> وبما ان بروتوتايب ال <code>()Person</code> هو ال <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code> وال <strong><code>person1</code></strong> هو من يمثله فسيرث ال <strong><code>person1</code></strong> هذه الخاصية من <code>Object</code>. مهمة ال <code>valueOf</code> هي العودة بقيمة الكائن الذي تم استدعاؤها عليه، حاول تجربتها وسترى ما الذي سيحدث.</p> + +<p dir="rtl">في هذه الحالة ستسير عملية البحث على الشكل التالي:</p> + +<ul dir="rtl"> + <li>في البداية سيقوم المتصفح بالتحقق ما اذا كان الكائن <strong><code>person1</code></strong> يحتوي على الوظيفة <code>()valueOf</code>. (لاحظ هنا، بدا البحث من اسفل السلسلة كما ذكرنا اعلاه).</li> + <li>اذا لم يتم ذالك، سيقوم المتصفح بالتحقق ما اذا كان ال Person() constructor يحتوي على الوظيفة <code>()valueOf</code></li> + <li>اذا لم يتم ذالك، سيقوم المتصفح بالتحقق ما اذا كان <code>prototype</code> ال Person() constructor يحتوي على الوظيفة <code>()valueOf</code></li> + <li>اذا لم يتم ذالك ايضا، سيقوم المتصفح بالتحقق ما اذا كان <code>__proto__</code> ال Person() constructor الذي هو (Object) يحتوي على الوظيفة <code>()valueOf</code><br> + اذا تم، ستستدعى الوظيفة المطلوبة للعمل عليها، وكل شئ على ما يرام. اذا لم يجد ما يبحث عنه من ادنى السلسلة الى اعلاها، سيعود ب <strong><code>null</code></strong> (و <code>null</code> هي اعلى السلسلة).</li> +</ul> + +<div class="note" dir="rtl"> +<p>تذكير: الخصائص والوظائف لا يتم نسخها من كائن إلى آخر في ال ptototype chain —<br> + بل يتم الوصول إليها من خلال التنقل صعودا في السلسلة كما هو موضح أعلاه.</p> +</div> + +<div class="note" dir="rtl"> +<p><strong>ملاحظة:</strong> رسميا لا توجد طريقة للوصول مباشرة الى الكائن prototype داخل كائن. "الروابط" بين العناصر موجودة في السلسلة ويتم تعريفها في خاصية داخلية، يشار إليها ب [[prototype]] في مواصفات لغة جافا سكريبت (see {{glossary("ECMAScript")}}). ومع ذلك فمعظم المتصفحات الحديثة تحتوي على خاصية متاحة لها تسمى <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto">__proto__</a></code> (لديها 2 underscores في كلا جوانبها), والتي تحتوي على الكائن prototype. على سبيل المثال جرب:<br> + <code> __</code><strong><code>person1.__proto</code> او <code> __eprson1.__proto__.__proto</code></strong><br> + لمشاهدة ما يشبه السلسلة في التعليمات البرمجية!</p> +</div> + +<h2 dir="rtl" id="الخاصية_prototype_اين_يتم_تعريف_الأعضاء_الموروثة">الخاصية prototype : اين يتم تعريف الأعضاء الموروثة</h2> + +<p dir="rtl">اذاً، أين يتم تعريف الخصائص والوظائف الموروثة؟<br> + إذا نظرتم إلى صفحة مرجع ال <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code> سترون هناك في الجانب الأيسر عددا كبيرا من الخصائص والوظائف المدرجة، البعض منها موروثة، واخرى غير موروثة، لم هذا؟</p> + +<p dir="rtl">الجواب، هو أن الاعضاء الموروثة هي تلك المعرفة في الخاصية prototype (يمكن استدعاؤها تحت ال namespace)، اي تلك التي تبدأ ب <strong>.<code>Object.prototype</code></strong> وليست تلك التي تبدأ بمجرد <strong>.<code>Object</code></strong>، قيمة الخاصية prototype هي كائن، والتي هي في الاساس حزمة او وعاء لتخزين الخصائص والوظائف التي نريدها أن تكون موروثة من قبل الكائنات السفلية في ال prototype chain.</p> + +<p dir="rtl">حتى ال <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf">()</a></code><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch">Object.prototype.watch</a></code> او <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch">()</a></code><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf">Object.prototype.valueOf</a></code>، متاحة لأي نوع من أنواع الكائنات التي ترث من ال <strong><code>Object.prototype</code></strong> بما في ذلك ال object instances الجديدة التي يتم إنشاؤها من ال constructor، (ك <code>person1</code> مثلا).</p> + +<p dir="rtl"><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">()</a><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is">Object.is()</a></code> ،<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys</a></code>، والأعضاء الاخرى غير معرفة داخل حزمة ال prototype وهي غير موروثة بواسطة ال object instances أو أنواع الكائنات التي ترث من ال ()Object. هي خصائص ووظائف متاحة فقط لل Object() constructor نفسه.</p> + +<div class="note" dir="rtl"> +<p><strong>ملاحظة:</strong> يبدو هذا غريبا - كيف يمكن أن يكون لديك وظيفة معرفة في ال constructor، الذي هو في حد ذاته function؟ حسنا، هي ايضا function من النوع object - راجع مرجع ال <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function">Function()</a></code> constructor حتى تتاكد بنفسك.</p> +</div> + +<p dir="rtl">يمكنك التحقق من خصائص البروتوتايب الموجودة بنفسك، ارجع الى مثالنا السابق وحاول ادخال السطر التالي في الجافاسكريبت console:</p> + +<pre class="brush: js">Person.prototype</pre> + +<p dir="rtl">المخرجات لن تظهر لك الكثير، لاننا حتى الان، لم نقم باضافة أي شيء في بروتوتايب ال constructor الخاص بنا، بشكل افتراضي، دائماً يبدأ بروتوتايب ال constructor فارغا. الآن جرب ما يلي:</p> + +<pre class="brush: js">Object.prototype</pre> + +<p dir="rtl">سترى عددا كبيرا من الوظائف المعرفة في الخاصية <code>prototype</code> الخاصة بال <code>Object</code>، ثم التي تتوفر على الكائنات التي ترث من ال <code>Object</code>، كما وضحنا في وقت سابق.</p> + +<p dir="rtl">سنرى أمثلة أخرى للوراثة عن طريق سلسلة البروتوتايب <strong><code>prototype chain</code></strong> في جميع أنحاء جافا سكريبت، حاول البحث في الوظائف والخصائص المعرفة في بروتوتايب الكائنات العامة ك <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code> <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">،Date</a></code> <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number">،Number</a></code>، و <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code> على سبيل المثال. كلها تحتوي على عدد من الأعضاء المعرفة في البروتوتايب الخاص بها، على سبيل المثال عندما نقوم بإنشاء سلسلة نصية (string)، مثل هذه:</p> + +<pre class="brush: js">var myString = 'This is my string.';</pre> + +<p dir="rtl"><code>myString</code>، فور انشائها سيتاح لها العديد من الوظائف المفيدة، مثل <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split">()</a></code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split">split</a></code> و <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split">()</a><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf">indexOf</a></code> و <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf">()</a></code><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace">replace</a></code> ... الخ.</p> + +<div class="warning" dir="rtl"> +<p><strong>هام</strong>: الخاصية prototype هي واحدة من أكثر الاجزاء ارباكا لجافا سكريبت، قد تعتقد أن <code>this</code> تشير الى الكائن prototype للكائن الحالي، لكن ليس هذا ما يحدث (تذكر ان هذا كائن داخلي يمكن الوصول إليه بواسطة ال __proto__ ). ال prototype هي خاصية تحتوي على الكائن الذي ستعرف فيه الاعضاء التي تريدها أن تكون موروثة.</p> +</div> + +<h2 dir="rtl" id="إعادة_النظر_في_الوظيفة_()create">إعادة النظر في الوظيفة ()create</h2> + +<p dir="rtl">راينا سابقا كيف يمكن استخدام الوظيفة <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">()</a></code><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create</a></code> لانشاء object instance.</p> + +<p dir="rtl">على سبيل المثال، حاول تجربة هذا في console الجافا سكريبت في المثال الخاص بك:</p> + +<pre class="brush: js">var person2 = Object.create(person1);</pre> + +<p dir="rtl">ماتفعله الوظيفة <code>()create</code> في الواقع هو انشاء كائن جديد، من الكائن <code>prototype</code> المحدد، في هذه الحالة، سيتم إنشاء <code>person2</code> باستخدام <code>person1</code> على شكل كائن <code>prototype</code>، يمكنك التحقق من ذلك عن طريق إدخال ما يلي في ال console :</p> + +<pre class="brush: js">person2.__proto__</pre> + +<p dir="rtl">النتيجة: إرجاع الكائن <code>person1</code>.</p> + +<h2 dir="rtl" id="الخاصية_constructor">الخاصية constructor</h2> + +<p dir="rtl">كل object instance يحتوي على الخاصية <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor">constructor</a></code> والتي تشير إلى ال constructor function الأصلي الذي أنشأ ال instance.</p> + +<p dir="rtl">على سبيل المثال، حاول ادخال هذه الأوامر في ال console:</p> + +<pre class="brush: js">person1.constructor +person2.constructor</pre> + +<p dir="rtl">المفروض على كل منهما العودة لل Person() constructor، كما سيحتوي كل منهما على التعريف الأصلي لهذه ال instances.</p> + +<p dir="rtl">خدعة ذكية، يمكنك وضع الاقواس في نهاية الخاصية constructor (مع البرامترات المطلوبة) لانشاء object instance اخر من هذا ال constructor، ال constructor هو في النهاية function، لذالك يمكنك استدعاؤها باستخدام الأقواس، ستحتاج فقط إلى تضمين الكلمة المحجوزة new لتحديد أنك تريد استخدام هذه ال function ك constructor.</p> + +<p dir="rtl">حاول ادخال هذا في ال console:</p> + +<pre class="brush: js">var person3 = new person1.constructor('Karen', 'Stephenson', 26, 'female', ['playing drums', 'mountain climbing']);</pre> + +<p dir="rtl"><span id="result_box" lang="ar"><span>الآن</span> <span>حاول الوصول إلى</span> <span>خصائص الكائن</span> <span>الجديد الخاص بك</span><span>، على سبيل المثال</span><span>:</span></span></p> + +<pre class="brush: js" dir="rtl">person3.name.first +person3.age +person3.bio()</pre> + +<p dir="rtl">هذا سيعمل بشكل جيد. وعلى الارجح لن تحتاج لاستخدامه في كثير من الأحيان، ولكن يمكن أن يكون مفيدا حقا، عندما تريد إنشاء instance جديد لا يشير إلى ال constructor الأصلي <span id="result_box" lang="ar"><span>المتاح</span></span>.</p> + +<p dir="rtl">الخاصية constructor لها استخدامات أخرى كذالك. على سبيل المثال، إذا كان لديك<br> + object instance وترغب في إرجاع اسم ال contructor وهو instance، يمكنك استخدام ما يلي:</p> + +<pre class="brush: js">instanceName.constructor.name</pre> + +<p dir="rtl">جرب هذا، على سبيل المثال:</p> + +<pre class="brush: js">person1.constructor.name</pre> + +<h3 dir="rtl" id="التعديل_على_ال_prototypes">التعديل على ال prototypes</h3> + +<p dir="rtl"><span id="result_box" lang="ar"><span>دعونا نلقي</span> <span>نظرة على مثال</span> يقوم <span>بتعديل</span><span> الخاصية</span> </span> <code>prototype</code> <span lang="ar"><span>الخاصة بال</span> </span>constructor<span lang="ar"><span>.</span></span></p> + +<p dir="rtl">نعود إلى مثالنا <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">oojs-class-further-exercises.html</a> قم بعمل نسخة من الكود التالي <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">source code</a>. اسفل كود الجافاسكريبت، اضف التعليمة البرمجية التالية، وهي خاصة باظافة وظيفة جديدة على بروتوتايب ال constructor : </p> + +<pre class="brush: js">Person.prototype.farewell = function() { + alert(this.name.first + ' has left the building. Bye for now!'); +}</pre> + +<p dir="rtl">احفظ التعليمات البرمجية وقم بتحميل الصفحة في المتصفح، وحاول إدخال ما يلي في حقل المدخلات الخاص بك:</p> + +<pre class="brush: js">person1.farewell();</pre> + +<p dir="rtl">ستحصل على رسالة تنبيه معروضة (alert)، تضم اسم الشخص كما هو محدد داخل ال constructor. وهذا مفيد حقاً، ولكن الاكثر افائدة هو أنه سيتم تحديث سلسلة الوراثة باكملها بشكل حيوي، و بشكل تلقائي يتم جعل الوظيفة الجديدة متاحة لجميع ال object instances المشتقة من ال constructor.</p> + +<p dir="rtl">لنفكر في هذا للحظة. في التعليمة البرمجية خاصتنا، قمنا بتعريف ال Person constructor<br> + ثم قمنا بانشاء instance object من هذا ال Person constructor وهو ال person1 ثم قمنا باظافة الوظيفة الجديدة على بروتوتايب ال Person constructor.</p> + +<pre class="brush: js">function Person(first, last, age, gender, interests) { + + // property and method definitions + +}; + +var person1 = new Person('Tammi', 'Smith', 32, 'neutral', ['music', 'skiing', 'kickboxing']); + +Person.prototype.farewell = function() { + alert(this.name.first + ' has left the building. Bye for now!'); +}</pre> + +<p dir="rtl">ولكن الوظيفة <code>()farewell</code> لا تزال متاحة في ال <code>person1</code> object instance —<span id="result_box" lang="ar"><span> تم</span> تحديث <span>الوظائف</span> <span>المتاحة لها</span> <span>تلقائيا</span></span>، هذا يثبت ما قلناه سابقا عن ال <code>prototype chain</code>. والمتصفح سيبحث صعودا في السلسلة لإيجاد الوظائف التي لم يتم تعريفها في ال object instance نفسها، بدلا من تلك الوظائف التي يتم نسخها إلى ال instance. وهذا يجعلها قوية جداً، و نظامها الوظيفي قابل للتوسع/للتمدد.</p> + +<div class="note" dir="rtl"> +<p><strong>Note</strong>: إذا كنت تواجه صعوبة في الحصول على هذا العمل, الق نظرة على المثال الخاص بنا <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-prototype.html">oojs-class-prototype.html</a> (شاهد ايضا <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-prototype.html">running live</a> ).</p> +</div> + +<p dir="rtl">نادرا ما ستشاهد خصائص معرفة في الخاصية prototype، على سبيل المثال يمكن إضافة خاصية جديدة كالتالي:</p> + +<pre class="brush: js">Person.prototype.fullName = 'Bob Smith';</pre> + +<p dir="rtl">ولكن هذه ليست مرنة جداً، حيث ان ال person لا يمكنه استدعاءها، من الافضل القيام بذلك من خلال بناء <code>fullName</code> خارج <code>name.first</code> و <code>name.last</code>:</p> + +<pre class="brush: js">Person.prototype.fullName = this.name.first + ' ' + this.name.last;</pre> + +<p dir="rtl">ومع ذالك فهي لن تعمل، في هذه الحالة <code><strong>this</strong></code> ستشير الى النطاق العام (global scope). وليس الى نطاق الدالة (function scope). استدعاء هذه الخاصية سيعود ب undefined undefined. سيعمل هذا بشكل جيد في الوظائف التي عرفناها سابقا في ال prototype لانها توجد داخل ال function scope، والتي ستنقل بنجاح إلى نطاق مثيل الكائن (object instance scope). لذا قد تقوم بتعريف خصائص ثابتة (constant properties — أي تلك التي لا تحتاج للتغيير) في ال prototype، ولكن عموما فهي تعمل بشكل أفضل لتعريف خصائص داخل ال constructor.</p> + +<p dir="rtl">في الواقع، النمط الشائع إلى حد كبير بخصوص تعريف الكائن، هو ان يتم تحديد الخصائص داخل ال constructor، والوظائف على ال prototype. وهذا يجعل الكود اسهل في القراءة، كما سيحتوي ال constructor على الخصائص المعرفة فقط، ويتم تقسيم الوظائف في بلوكات منفصلة، مثلا:</p> + +<pre class="brush: js">// Constructor with property definitions + +function Test(a,b,c,d) { + // property definitions +}; + +// First method definition + +Test.prototype.x = function () { ... } + +// Second method definition + +Test.prototype.y = function () { ... } + +// etc.</pre> + +<p dir="rtl">هذا النمط من العمل يمكن ان نراه في Piotr Zalewa's <a href="https://github.com/zalun/school-plan-app/blob/master/stage9/js/index.js">school plan app</a>.</p> + +<h3 id="Summary">Summary</h3> + +<p dir="rtl">غطت هذه المادة، جافاسكريبت <strong><code>object prototypes</code></strong>، وكيف يسمح ال prototype object chains للكائنات أن ترث الميزات من بعضها البعض، وكيف يمكن استخدام الخاصية prototype لإضافة وظائف جديدة على ال constructors، وغيرها من الموضوعات ذات الصلة.</p> + +<p><strong>في المقال القادم سنرى كيفية تنفيذ الوراثة بين اثنين من الكائنات الخاصة بك.</strong></p> +</div> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}</p> |