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
|
---
title: ()Function.prototype.call
slug: Web/JavaScript/Reference/Global_Objects/Function/call
translation_of: Web/JavaScript/Reference/Global_Objects/Function/call
---
<div>{{JSRef}}</div>
<div style="font-family: tahoma; font-size: 15px;">
<p dir="rtl">تُستدعَى الوظيفة <code>()call</code> على دالة، أول argument لهذه الوظيفة هو قيمة <code>this</code> الخاصة بالدالة، وال arguments المتبقية (إن وُجدت)، هي arguments الدالة.</p>
<div class="note" dir="rtl">
<p><strong>ملاحظة : </strong> صيغة هذه الوظيفة مماثلة تقريبًا للصيغة الخاصة بـ {{jsxref("Function.prototype.apply", "apply")}} الفرق الوحيد هو ان <strong> </strong><code>()call</code><strong> </strong>تاخذ قائمة من ال <strong>arguments</strong> محددة بشكل فردي فيما تاخذ <code>()apply</code> مصفوفة واحدة من ال <strong>arguments</strong>.</p>
</div>
<div>{{EmbedInteractiveExample("pages/js/function-call.html")}}</div>
<h2 dir="rtl" id="صيغة_الوظيفة_call">صيغة الوظيفة call</h2>
<pre class="syntaxbox notranslate"><code><var>function</var>.call(<var>thisArg</var>, <var>arg1</var>, <var>arg2</var>, ...)</code></pre>
<h3 id="Parameters">Parameters</h3>
<dl>
<dt dir="rtl"><code>thisArg</code></dt>
<dd dir="rtl">اختياري. وهو قيمة <code>this</code> المتوفرة في استدعاء الدالة <code><var>function</var></code>. لاحظ أن <code>this</code> قد لا تكون القيمة الفعلية التي تراها الوظيفة: اذا كانت هذه الوظيفة دالة في {{jsxref("Strict_mode", "non-strict mode", "", 1)}} سيتم استبدال {{jsxref("Global_Objects/null", "null")}} و {{jsxref("Global_Objects/undefined", "undefined")}} بالكائن العام والقيم الاولية ستحول الى كائنات. </dd>
<dt dir="rtl"><code>...,arg1, arg2</code></dt>
<dd dir="rtl"> arguments الدالة <code><var>function</var></code>.</dd>
</dl>
<h3 dir="rtl" id="Return_value">Return value</h3>
<p dir="rtl">تُرجع نتيجة استدعاء الدالة مع قيمة <strong> </strong><code>this</code> المحددة و ال arguments.</p>
<h2 dir="rtl" id="وصف">وصف</h2>
<p dir="rtl">تسمح الوظيفة <code>()call</code> لدالة او وظيفة خاصة بكائن واحد بان يتم استدعاؤها وتعيينها من قبل كائن مختلف.</p>
<p dir="rtl">تمنح الوظيفة <code>()call</code> قيمة <code>this</code> الجديدة الى الدالة/الوظيفة. مع الـ <code>call</code> يمكنك كتابة الوظيفة مرة واحدة ومن ثم تقوم بتوريثها لكائن آخر دون الحاجة إلى إعادة كتابة الوظيفة للكائن الجديد.</p>
<h2 dir="rtl" id="تحليل_الجزء_الغامض_في_الوظيفة_call">تحليل الجزء الغامض في الوظيفة <code>()call</code></h2>
<p dir="rtl">نظرا لعدم وجود شرح كاف حول هذه الجزئية فقد ارتايت ان اظيف هذه الفقرة التوضيحية لعلها تزيح بعض الغموض عن قيمة ال <code>this</code> التي تمثل ال argument الاول لهذه الوظيفة.</p>
<p dir="rtl">اذا نظرنا بتمعن في هذا الجزء من داخل الوظيفة <code>call</code>. سنجد ان thisArg ستساوي الكائن العام في حالة undefined او null، والا ستساوي ناتج الكائن Object، تساوي thisArg كائنا في كلتا الحالتين. وعليه فقد اصبحت كائنا، اذن فمن الطبيعي ان تمتلك خصائص. تم تحديد الخاصية _callTemp_ قيمتها this و this تمثل الدالة التي ستستدعى عليها الوظيفة <code>call</code>. واخيرا يتم تنفيذ هذه الدالة:</p>
<pre class="brush: js notranslate">Function.prototype.call_like = function( thisArg, args ){
thisArg = ( thisArg === undefined || thisArg === null ) ? window : Object( thisArg );
thisArg._callTemp_ = this;
thisArg._callTemp_();
}</pre>
<p dir="rtl">في حالة عدم وجود thisArg ستتصرف الدالة fn بشكل طبيعي و this ستساوي الكائن العام:</p>
<pre class="brush: js notranslate">var fn = function () {
console.log( this ); // [object Window]
}
fn.call_like();
</pre>
<p dir="rtl">في حالة وجود thisArg بقيمة اولية ك undefined او null ف this ستساوي ايضا الكائن العام، خلاف ذالك سيتم تمرير قيمتها الى الكائن <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">()</a><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a>، اذا كانت هذه القيمة من القيم الاولية-<a href="https://developer.mozilla.org/en-US/docs/Glossary/Primitive">primitive value</a> سيقوم الكائن بتحويلها الى الكائن المناسب لها، واما اذا كانت هذه القيمة كائنا فلا حاجة لتحويلها و this ستساوي كائنا.</p>
<p dir="rtl">وهذا يفسر كيف قام الكائن Object بتحويل القيمة الاولية <code>"Youssef belmeskine"</code> الى الكائن String: </p>
<pre class="brush: js notranslate">var fn = function () {
console.log( this ); // "Youssef belmeskine"
console.log( this === "Youssef belmeskine" ); // false
console.log( String(this) === "Youssef belmeskine" ); // true
}
fn.call_like( "Youssef belmeskine" );
</pre>
<p dir="rtl">من المهم دائما ذكر المصدر:</p>
<div class="blockIndicator note">
<p dir="rtl">بالنسبة لى شخصيا لم اتمكن من فهم هذه الوظيفة وشقيقتها apply بشكل واضح الا عندما قمت بالاطلاع على الكود الداخلى لها. قمت باستخدام هذا الجزء من الكود لتوضيح الفكرة فقط. ستجد ال Polyfill كاملا في هذا الموقع <a href="https://hexmen.com/blog/2006/12/26/revisiting-functionprototypeapply-for-ie5/">hexmen.com.</a></p>
</div>
<h2 dir="rtl" id="أمثلة">أمثلة</h2>
<h3 dir="rtl" id="استخدام_ال_call_لِسَلسَلة_منشئات_الكائن">استخدام ال <code>call</code> لِسَلسَلة منشئات الكائن</h3>
<p dir="rtl">تستطيع إستخدام <code>call</code> لعمل تسلسل لمنشئات-constructors الكائن، وذلك على غرار جافا. في المثال التالي، تم تحديد منشئ الكائن <code>Product</code> مع اثنين من البارامترات <code>name</code> و <code>price</code>. والدالتات <code>Food</code> و <code>Toy</code> تستدعيان <code>Product</code> ممرر لها <code>this</code> و <code>name</code> و <code>price</code>. تقوم Product بتهيئة الخاصيتان <code>name</code> و <code>price</code> فيما تقوم كلا الدالتان المتخصصتان بتحديد ال <code>category</code>.</p>
<pre class="brush: js notranslate">function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
function Toy(name, price) {
Product.call(this, name, price);
this.category = 'toy';
}
var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);
</pre>
<h3 dir="rtl" id="إستخدام_ال_call_لإستدعاء_الدالة_المجهولة_الاسم-anonymous_function">إستخدام ال call لإستدعاء الدالة المجهولة الاسم-anonymous function </h3>
<p dir="rtl">في هذا المثال قمنا بانشاء الدالة المجهولة واستخدمنا <code>call</code> لإستدعاءها على كل كائن في المصفوفة. الغرض الرئيسي من الدالة المجهولة هو إضافة الدالة <code>print</code> الى كل كائن، والتي ستكون قادرة على طباعة الفهرس الصحيح لكائنات المصفوفة. تمرير كائن على شكل قيمة <code>this</code><span id="result_box" lang="ar"><span> </span></span><span lang="ar"><span>ليس ضروريًا، ولكن تم إنجازه لغرض توضيحي.</span></span></p>
<pre class="brush: js notranslate">var animals = [
{ species: 'Lion', name: 'King' },
{ species: 'Whale', name: 'Fail' }
];
for (var i = 0; i < animals.length; i++) {
(function(i) {
this.print = function() {
console.log('#' + i + ' ' + this.species
+ ': ' + this.name);
}
this.print();
}).call(animals[i], i);
}
</pre>
<h3 dir="rtl" id="استخدام_call_لاستدعاء_دالة_وتحديد_السياق-context_ل_this">استخدام <code>call</code> لاستدعاء دالة وتحديد السياق-context ل <code>this</code></h3>
<p dir="rtl">في المثال أدناه، عندما سنقوم باستدعاء <code>greet</code> سترتبط قيمة <code>this</code> بالكائن <code>obj.</code></p>
<pre class="brush: js notranslate">function greet() {
var reply = [this.animal, 'typically sleep between', this.sleepDuration].join(' ');
console.log(reply);
}
var obj = {
animal: 'cats', sleepDuration: '12 and 16 hours'
};
greet.call(obj); // cats typically sleep between 12 and 16 hours
</pre>
<h3 dir="rtl" id="إستخدام_الـcall_لاستدعاء_دالة_وبدون_تحديد_البرامتر_الاول">إستخدام الـ<code>call</code> لاستدعاء دالة وبدون تحديد البرامتر الاول</h3>
<p dir="rtl">في المثال أدناه ،قمنا باستدعاء الدالة <code>display</code> من دون تمرير البرامتر الاول. إذا لم يتم تمرير قيمة <code>this</code> في البرامتر الاول فسترتبط بالكائن العام-global object.</p>
</div>
<pre class="brush: js notranslate">var sData = 'Wisen';
function display(){
console.log('sData value is %s ', this.sData);
}
display.call(); // sData value is Wisen
</pre>
<div class="blockIndicator note" dir="rtl">
<p>تذكر ان قيمة <code>this</code> ستكون ب <code>undefined</code> في الوضع الصارم. انظر ادناه:</p>
</div>
<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="string token">'use strict'</span><span class="punctuation token">;</span>
<span class="keyword token">var</span> sData <span class="operator token">=</span> <span class="string token">'Wisen'</span><span class="punctuation token">;</span>
<span class="keyword token">function</span> <span class="function token">display</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="string token">'sData value is %s '</span><span class="punctuation token">,</span> <span class="keyword token">this</span><span class="punctuation token">.</span>sData<span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>
display<span class="punctuation token">.</span><span class="function token">call</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// Cannot read the property of 'sData' of undefined</span></code></pre>
<h2 id="Specifications">Specifications</h2>
<table class="standard-table">
<thead>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName('ES1')}}</td>
<td>{{Spec2('ES1')}}</td>
<td>Initial definition. Implemented in JavaScript 1.3.</td>
</tr>
<tr>
<td>{{SpecName('ES5.1', '#sec-15.3.4.4', 'Function.prototype.call')}}</td>
<td>{{Spec2('ES5.1')}}</td>
<td></td>
</tr>
<tr>
<td>{{SpecName('ES6', '#sec-function.prototype.call', 'Function.prototype.call')}}</td>
<td>{{Spec2('ES6')}}</td>
<td></td>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-function.prototype.call', 'Function.prototype.call')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="Browser_compatibility">Browser compatibility</h2>
<p>{{Compat("javascript.builtins.Function.call")}}</p>
<h2 id="See_also">See also</h2>
<ul>
<li>{{jsxref("Function.prototype.bind()")}}</li>
<li>{{jsxref("Function.prototype.apply()")}}</li>
<li>
<p><a href="/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript">Introduction to Object-Oriented JavaScript</a></p>
</li>
</ul>
|