Skip to content

Commit 2b83145

Browse files
committed
Translating Rest Parameters amd Spread Operator to Ar
1 parent 9a3c8d9 commit 2b83145

1 file changed

Lines changed: 112 additions & 97 deletions

File tree

  • 1-js/06-advanced-functions/02-rest-parameters-spread

1-js/06-advanced-functions/02-rest-parameters-spread/article.md

Lines changed: 112 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
1-
# Rest parameters and spread syntax
1+
# المُعاملات «البقية» ومُعامل التوزيع
22

3-
Many JavaScript built-in functions support an arbitrary number of arguments.
3+
تتوقّع العديد من دوال جافاسكربت المضمّنة في اللغة عددًا من الوُسطاء لا ينتهي.
44

5-
For instance:
5+
مثال:
66

7-
- `Math.max(arg1, arg2, ..., argN)` -- returns the greatest of the arguments.
8-
- `Object.assign(dest, src1, ..., srcN)` -- copies properties from `src1..N` into `dest`.
9-
- ...and so on.
7+
- `Math.max(arg1, arg2, ..., argN)` -- يُعيد أكبر وسيط من الوُسطاء.
8+
- `Object.assign(dest, src1, ..., srcN)` -- ينسخ الخصائص من `src1..N` إلى `dest`.
9+
- ...وهكذا.
1010

11-
In this chapter we'll learn how to do the same. And also, how to pass arrays to such functions as parameters.
1211

13-
## Rest parameters `...`
12+
سنتعلّم في هذا الفصل كيف نفعل ذلك أيضًا. كما وكيف نمرّر المصفوفات إلى هذه الدوال على أنّها مُعاملات.
13+
14+
## المُعاملات «البقية» `...`
15+
16+
يمكن أن ننادي الدالة بأيّ عدد من الوُسطاء كيفما كانت معرّفة الدالة.
17+
18+
هكذا:
1419

15-
A function can be called with any number of arguments, no matter how it is defined.
1620

17-
Like here:
1821
```js run
1922
function sum(a, b) {
2023
return a + b;
@@ -23,14 +26,14 @@ function sum(a, b) {
2326
alert( sum(1, 2, 3, 4, 5) );
2427
```
2528

26-
There will be no error because of "excessive" arguments. But of course in the result only the first two will be counted.
29+
لن ترى أيّ خطأ بسبب تلك الوُسطاء «الزائدة». ولكن طبعًا فالنتيجة لن تأخذ بالحسبان إلا أوّل اثنين.
2730

28-
The rest of the parameters can be included in the function definition by using three dots `...` followed by the name of the array that will contain them. The dots literally mean "gather the remaining parameters into an array".
31+
يمكن تضمين بقية المُعاملات في تعريف الدالة باستعمال الثلاث نقاط `...` ثمّ اسم المصفوفة التي ستحتويهم. تعني تلك النقط حرفيًا «اجمع المُعاملات الباقية في مصفوفة».
2932

30-
For instance, to gather all arguments into array `args`:
33+
فمثلًا لجمع كلّ الوُسطاء في المصفوفة `args`:
3134

3235
```js run
33-
function sumAll(...args) { // args is the name for the array
36+
function sumAll(...args) { // ‫اسم المصفوفة هو args
3437
let sum = 0;
3538

3639
for (let arg of args) sum += arg;
@@ -43,71 +46,74 @@ alert( sumAll(1, 2) ); // 3
4346
alert( sumAll(1, 2, 3) ); // 6
4447
```
4548

46-
We can choose to get the first parameters as variables, and gather only the rest.
49+
يمكن لو أردنا أن نأخذ المُعاملات الأولى في متغيّرات ونجمع البقية فقط.
4750

48-
Here the first two arguments go into variables and the rest go into `titles` array:
51+
هنا نأخذ الوسيطين الأوليين في متغيرات والباقي نرميه في المصفوفة `titles`:
4952

5053
```js run
5154
function showName(firstName, lastName, ...titles) {
5255
alert( firstName + ' ' + lastName ); // Julius Caesar
5356

54-
// the rest go into titles array
55-
// i.e. titles = ["Consul", "Imperator"]
57+
// ‫الباقي نضعه في مصفوفة الأسماء titles
58+
// ‫مثلًا titles = ["Consul", "Imperator"]
5659
alert( titles[0] ); // Consul
5760
alert( titles[1] ); // Imperator
5861
alert( titles.length ); // 2
5962
}
6063

6164
showName("Julius", "Caesar", "Consul", "Imperator");
65+
6266
```
6367

64-
````warn header="The rest parameters must be at the end"
65-
The rest parameters gather all remaining arguments, so the following does not make sense and causes an error:
68+
````warn header="يجب أن تُترك المُعاملات البقية إلى النهاية"
69+
تجمع المُعاملات البقية كلّ الوُسطاء التي بقيت. وبهذا فالآتي ليس منطقيًا وسيتسبّب بخطأ:
6670
6771
```js
68-
function f(arg1, ...rest, arg2) { // arg2 after ...rest ?!
69-
// error
72+
function f(arg1, ...rest, arg2) { // ‫الوسيط arg2 بعد ...البقية؟!
73+
// خطأ
7074
}
75+
7176
```
7277
73-
The `...rest` must always be last.
78+
يجب أن يكون `‎...rest‎` الأخير دومًا.
7479
````
7580

76-
## The "arguments" variable
81+
## متغيّر الوُسطاء arguments
82+
83+
هناك كائن آخر شبيه بالمصفوفات يُدعى `‎arguments‎` ويحتوي على كلّ الوُسطاء حسب ترتيب فهارسها.
7784

78-
There is also a special array-like object named `arguments` that contains all arguments by their index.
85+
مثال:
7986

80-
For instance:
8187

8288
```js run
8389
function showName() {
8490
alert( arguments.length );
8591
alert( arguments[0] );
8692
alert( arguments[1] );
8793

88-
// it's iterable
94+
// المصفوفة مُتعدَّدة
8995
// for(let arg of arguments) alert(arg);
9096
}
9197

92-
// shows: 2, Julius, Caesar
98+
// ‫تعرض: 2, Julius, Caesar
9399
showName("Julius", "Caesar");
94100

95-
// shows: 1, Ilya, undefined (no second argument)
101+
// ‫تعرض: 1, Ilya, undefined (ما من مُعطى ثانٍ)
96102
showName("Ilya");
103+
97104
```
98105

99-
In old times, rest parameters did not exist in the language, and using `arguments` was the only way to get all arguments of the function. And it still works, we can find it in the old code.
106+
قديمًا لم تكن المُعاملات البقية موجودة في اللغة ولم يكن لدينا سوى استعمال `arguments` لنجلب كلّ مُعاملات الدالة. وما زالت تعمل الطريقة إلى يومنا هذا ويمكن أن تراها في الشيفرات القديمة.
100107

101-
But the downside is that although `arguments` is both array-like and iterable, it's not an array. It does not support array methods, so we can't call `arguments.map(...)` for example.
108+
ولكن السلبية هنا هي أنّ `arguments` ليست مصفوفة (على الرغم من أنّها شبيهة بالمصفوفات ومُتعدّدة). بهذا لا تدعم توابِع المصفوفات فلا ينفع أن نستدعي عليها `arguments.map(...)` مثلًا.
102109

103-
Also, it always contains all arguments. We can't capture them partially, like we did with rest parameters.
110+
كما وأنّها تحتوي على كل الوُسطاء دومًا. لا يمكن أن نأخذ منها ما نريد كما نفعل مع المُعاملات البقية.
104111

105-
So when we need these features, then rest parameters are preferred.
112+
لهذا متى ما احتجنا إلى ميزة كهذه، فالأفضل استعمال المُعاملات البقية بدلًا من `‎arguments‎`.
106113

107-
````smart header="Arrow functions do not have `\"arguments\"`"
108-
If we access the `arguments` object from an arrow function, it takes them from the outer "normal" function.
114+
**ليس للدوال السهمية `"arguments"‎`**
115+
لو حاولت الوصول إلى كائن الوُسطاء `arguments` من داخل الدالة السهمية، فستستلم الناتج من الدالة «الطبيعية» الخارجية. إليك مثالًا:
109116

110-
Here's an example:
111117

112118
```js run
113119
function f() {
@@ -117,173 +123,182 @@ function f() {
117123

118124
f(1); // 1
119125
```
126+
كما نذكر فليس للدوال السهمية قيمة `‎this‎` تخصّها، أمّا الآن صرنا نعلم بأنّ ليس لها كائن `‎arguments‎` أيضًا.
120127

121-
As we remember, arrow functions don't have their own `this`. Now we know they don't have the special `arguments` object either.
122-
````
123128

129+
## مُعامل التوزيع [#spread-syntax]
124130

125-
## Spread syntax [#spread-syntax]
131+
رأينا كيف نأخذ مصفوفة من قائمة من المُعطيات.
126132

127-
We've just seen how to get an array from the list of parameters.
133+
ولكن ماذا لو أردنا العكس من ذلك؟
128134

129-
But sometimes we need to do exactly the reverse.
135+
فمثلًا لنقل أردنا استعمال الدالة المبنية في اللغة Math.max والتي تُعيد أكبر عدد من القائمة:
130136

131-
For instance, there's a built-in function [Math.max](mdn:js/Math/max) that returns the greatest number from a list:
132137

133138
```js run
134139
alert( Math.max(3, 5, 1) ); // 5
135140
```
136141

137-
Now let's say we have an array `[3, 5, 1]`. How do we call `Math.max` with it?
138142

139-
Passing it "as is" won't work, because `Math.max` expects a list of numeric arguments, not a single array:
143+
لنقل أنّ لدينا المصفوفة `‎[3, 5, 1]‎`. كيف نستدعي `‎Math.max‎` عليها؟
144+
145+
لا ينفع تمريرها «كما هي» لأنّ `‎Math.max‎` يتوقّع قائمةً بالوُسطاء العددية لا مصفوفة واحدة:
146+
140147

141148
```js run
142149
let arr = [3, 5, 1];
143150

144-
*!*
145151
alert( Math.max(arr) ); // NaN
146-
*/!*
152+
147153
```
148154

149-
And surely we can't manually list items in the code `Math.max(arr[0], arr[1], arr[2])`, because we may be unsure how many there are. As our script executes, there could be a lot, or there could be none. And that would get ugly.
155+
وطبعًا لا يمكن أن نفكّ عناصر القائمة يدويًا في الشيفرة `Math.max(arr[0], arr[1], arr[2])` لأنّنا في حالات لا نعرف كم من عنصر هناك أصلًا. وما إن يتنفّذ السكربت يمكن أن يكون فيه أكبر مما كتبناه أو حتّى لا شيء أصلًا، وسنحصد لاحقًا ما جنته هذه الشيفرة.
150156

151-
*Spread syntax* to the rescue! It looks similar to rest parameters, also using `...`, but does quite the opposite.
157+
عاش مُنقذنا *مُعامل التوزيع*! عاش عاش عاش! من بعيد نراه مشابهًا تمامًا للمُعاملات البقية، كما ويستعمل `...`، إلّا أنّ وظيفته هي العكس تمامًا.
152158

153-
When `...arr` is used in the function call, it "expands" an iterable object `arr` into the list of arguments.
159+
فحين نستعمل `‎‎...arr‎` في استدعاء الدالة، «يتوسّع» الكائن المُتعدَّد `‎...arr‎` إلى قائمة من الوُسطاء.
160+
161+
فمثلًا نعود إلى `‎Math.max‎`:
154162

155-
For `Math.max`:
156163

157164
```js run
158165
let arr = [3, 5, 1];
159166

160-
alert( Math.max(...arr) ); // 5 (spread turns array into a list of arguments)
167+
// ‫5 (يحوّل التوزيع المصفوفة إلى قائمة من الوُسطاء)
168+
alert( Math.max(...arr) );
169+
161170
```
162171

163-
We also can pass multiple iterables this way:
172+
يمكن أيضًا أن نمرّر أكثر من مُتعدَّد واحد بهذه الطريقة:
164173

165174
```js run
166175
let arr1 = [1, -2, 3, 4];
167176
let arr2 = [8, 3, -8, 1];
168177

169178
alert( Math.max(...arr1, ...arr2) ); // 8
179+
170180
```
171181

172-
We can even combine the spread syntax with normal values:
182+
أو حتّى ندمج مُعامل التوزيع مع القيم العادية:
173183

174184

175185
```js run
176186
let arr1 = [1, -2, 3, 4];
177187
let arr2 = [8, 3, -8, 1];
178188

179189
alert( Math.max(1, ...arr1, 2, ...arr2, 25) ); // 25
190+
180191
```
181192

182-
Also, the spread syntax can be used to merge arrays:
193+
كما يمكن أن نستعمل مُعامل التوزيعة لدمج المصفوفات:
183194

184195
```js run
185196
let arr = [3, 5, 1];
186197
let arr2 = [8, 9, 15];
187198

188-
*!*
189199
let merged = [0, ...arr, 2, ...arr2];
190-
*/!*
191200

192-
alert(merged); // 0,3,5,1,2,8,9,15 (0, then arr, then 2, then arr2)
201+
alert(merged); // ‫0,3,5,1,2,8,9,15 (0 ثمّ arr ثمّ 2 ثمّ arr2)
202+
193203
```
204+
استعملنا في الأمثلة أعلاه مصفوفة لنشرح مُعامل التوزيع، إلّا أنّ المُتعدَّدات أيًا كانت تنفع أيضًا.
194205

195-
In the examples above we used an array to demonstrate the spread syntax, but any iterable will do.
206+
فمثلًا نستعمل هنا مُعامل التوزيع لنحوّل السلسلة النصية إلى مصفوفة محارف:
196207

197-
For instance, here we use the spread syntax to turn the string into array of characters:
198208

199209
```js run
200210
let str = "Hello";
201211

202212
alert( [...str] ); // H,e,l,l,o
213+
203214
```
204215

205-
The spread syntax internally uses iterators to gather elements, the same way as `for..of` does.
216+
يستعمل مُعامل التوزيع هذا داخليًا المُعدِّدات لجمع العناصر، كما تفعل حلقة `‎for..of‎`.
217+
218+
لذا لو استلمت `‎for..of‎` سلسلةً نصيّة فتُعيد لنا المحارف وتصير `‎‎...str‎` بالقيمة `‎"H","e","l","l","o"‎`. وهكذا تُمرّر قائمة المحارف إلى مُهيّئ المصفوفة `‎[...str]‎`.
206219

207-
So, for a string, `for..of` returns characters and `...str` becomes `"H","e","l","l","o"`. The list of characters is passed to array initializer `[...str]`.
220+
يمكننا أيضًا لهذه المهمة استعمال `‎Array.from‎` إذ أنّه يحوّل المُتعدَّد (مثل السلاسل النصية) إلى مصفوفة:
208221

209-
For this particular task we could also use `Array.from`, because it converts an iterable (like a string) into an array:
210222

211223
```js run
212224
let str = "Hello";
213225

214-
// Array.from converts an iterable into an array
226+
// ‫يُحوّل Array.from المُتعدَّد إلى مصفوفة
215227
alert( Array.from(str) ); // H,e,l,l,o
216228
```
217229

218-
The result is the same as `[...str]`.
230+
ناتجه هو ذات ناتج `‎[‎...str]`.
219231

220-
But there's a subtle difference between `Array.from(obj)` and `[...obj]`:
232+
ولكن... هناك فرق ضئيل بين `Array.from(obj)` و`[...obj]`:
221233

222-
- `Array.from` operates on both array-likes and iterables.
223-
- The spread syntax works only with iterables.
234+
- يعمل `Array.from` على الشبيهات بالمصفوفات والمُتعدَّدات.
235+
- ويعمل مُعامل التوزيع على المُتعدَّدات فقط لا غير.
224236

225-
So, for the task of turning something into an array, `Array.from` tends to be more universal.
237+
لذا لو أردت تحويل شيء إلى مصفوفة فالتابِع `Array.from` أكثر استعمالًا وشيوعًا.
226238

239+
## الحصول علي نسخة من المصفوفة/الكائن
227240

228-
## Get a new copy of an array/object
241+
تتذكر عندما تحدثنا عن `Object.assign()` [في الماضي](https://javascript.info/object#cloning-and-merging-object-assign)?
229242

230-
Remember when we talked about `Object.assign()` [in the past](https://javascript.info/object#cloning-and-merging-object-assign)?
243+
يمكن أن تقوم بالمثل عن طريق `...`.
231244

232-
It is possible to do the same thing with the spread syntax.
233245

234246
```js run
235247
let arr = [1, 2, 3];
236-
let arrCopy = [...arr]; // spread the array into a list of parameters
237-
// then put the result into a new array
248+
let arrCopy = [...arr]; // ننشر المصفوفة إلي قائمة من المعاملات
249+
// ثم نضع الناتج في مصفوفة جديدة
250+
251+
// هل المصفوفات تمتلك نفس القيمة؟
252+
alert(JSON.stringify(arr) === JSON.stringify(arrCopy)); // صحيح
238253

239-
// do the arrays have the same contents?
240-
alert(JSON.stringify(arr) === JSON.stringify(arrCopy)); // true
254+
// هل متساويين؟
255+
alert(arr === arrCopy); // خطأ (ليس نفس المرجع)
241256

242-
// are the arrays equal?
243-
alert(arr === arrCopy); // false (not same reference)
257+
// تعديل مصفوفتنا الأولى لا يتم تعديله في النسخة:
244258

245-
// modifying our initial array does not modify the copy:
246259
arr.push(4);
247260
alert(arr); // 1, 2, 3, 4
248261
alert(arrCopy); // 1, 2, 3
249262
```
263+
لاحظ أنه من الممكن أن نقوم بنفس الشئ لصنع نسخة من الكائن أيضاً:
250264

251-
Note that it is possible to do the same thing to make a copy of an object:
252265

253266
```js run
254267
let obj = { a: 1, b: 2, c: 3 };
255-
let objCopy = { ...obj }; // spread the object into a list of parameters
256-
// then return the result in a new object
268+
let objCopy = { ...obj }; // ننشر الكائن إلي قائمة من المعاملات
269+
// ثم نضع الناتج في كائن جديد
257270

258-
// do the objects have the same contents?
259-
alert(JSON.stringify(obj) === JSON.stringify(objCopy)); // true
271+
// هل الكائنات تمتلك نفس القيمة؟
272+
alert(JSON.stringify(obj) === JSON.stringify(objCopy)); // صحيح
260273

261-
// are the objects equal?
262-
alert(obj === objCopy); // false (not same reference)
274+
// هل متساويين؟
275+
alert(obj === objCopy); // خطأ (ليس نفس المرجع)
263276

264-
// modifying our initial object does not modify the copy:
277+
// تعديل الكائن الأول لا يعدل في النسخة
265278
obj.d = 4;
266279
alert(JSON.stringify(obj)); // {"a":1,"b":2,"c":3,"d":4}
267280
alert(JSON.stringify(objCopy)); // {"a":1,"b":2,"c":3}
268281
```
269282

270-
This way of copying an object is much shorter than `let objCopy = Object.assign({}, obj);` or for an array `let arrCopy = Object.assign([], arr);` so we prefer to use it whenever we can.
283+
هذه الطريقة أقصر بكثير من `let objCopy = Object.assign({}, obj);`
284+
285+
286+
## ملخص
271287

288+
متى رأينا `‎"..."‎` في الشيفرة نعرف أنّه إمّا المُعاملات البقية وأمّا مُعامل التوزيع.
272289

273-
## Summary
290+
إليك طريقة بسيطة للتفريق بينهما:
274291

275-
When we see `"..."` in the code, it is either rest parameters or the spread syntax.
292+
- حين ترى `‎...‎` موجودة في نهاية مُعاملات الدالة فهي «المُعاملات البقية» وستجمع بقية قائمة الوُسطاء في مصفوفة.
293+
- وحين ترى `‎...‎` في استدعاء دالة أو ما شابهه فهو «مُعامل توزيع» يوسّع المصفوفة إلى قائمة.
276294

277-
There's an easy way to distinguish between them:
295+
طُرق الاستعمال:
278296

279-
- When `...` is at the end of function parameters, it's "rest parameters" and gathers the rest of the list of arguments into an array.
280-
- When `...` occurs in a function call or alike, it's called a "spread syntax" and expands an array into a list.
297+
- تُستعمل المُعاملات البقية لإنشاء دوال تقبل أيّ عدد كان من الوُسطاء.
298+
- يُستعمل مُعامل التوزيع لتمرير مصفوفة إلى دوال تطلب (عادةً) قائمة طويلة من الوُسطاء.
281299

282-
Use patterns:
300+
كلا الميزتين تساعدك في التنقل بين القائمة ومصفوفة المُعاملات بسهولة ويُسر.
283301

284-
- Rest parameters are used to create functions that accept any number of arguments.
285-
- The spread syntax is used to pass an array to functions that normally require a list of many arguments.
302+
يمكنك أيضًا أن ترى كل وُسطاء استدعاء الدالة «بالطريقة القديمة» `‎arguments‎` وهو كائن مُتعدَّد شبيه بالمصفوفات.
286303

287-
Together they help to travel between a list and an array of parameters with ease.
288304

289-
All arguments of a function call are also available in "old-style" `arguments`: array-like iterable object.

0 commit comments

Comments
 (0)