1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
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>
|