Skip to content

translate part 1 2.12, 2.13 #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 38 additions & 38 deletions 1-js/02-first-steps/12-nullish-coalescing-operator/article.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
# Nullish coalescing operator '??'
# Nullish Coalescing Operator '??'

[recent browser="new"]

The nullish coalescing operator `??` provides a short syntax for selecting a first "defined" variable from the list.
Nullish Coalescing Operator `??` يقدم طريقة مختصرة لإختيار أول قيمة معرفة من قائمة متغيرات.

The result of `a ?? b` is:
- `a` if it's not `null` or `undefined`,
- `b`, otherwise.
نتيجة `a ?? b` تكون:
- `a` إذا لم تكن `null` أو `undefined`,
- `b`, غير ذلك.

So, `x = a ?? b` is a short equivalent to:
لذلك فإن `x = a ?? b` طريقة مختصرة للتالي:

```js
x = (a !== null && a !== undefined) ? a : b;
```

Here's a longer example.
هذا مثال أطول.

Let's say, we have a `firstName`, `lastName` or `nickName`, all of them optional.
لنفترض أن لدينا `firstName`, `lastName` أو `nickName` وجميعهم اختياريين.

Let's choose the defined one and show it (or "Anonymous" if nothing is set):
لنختار القيمة المعرفة ونعرضها (أو نعرض "Anonymous" إذا لم يحدد أي شئ):

```js run
let firstName = null;
Expand All @@ -29,25 +29,25 @@ let nickName = "Supercoder";
alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder
```

## Comparison with ||
## المقارنة مع ||

That's very similar to OR `||` operator. Actually, we can replace `??` with `||` in the code above and get the same result.
هذا مشابه جدًا للمعامل `||`. في الحقيقة يمكننا استبدال `??` ب `||` في المثال السابق وسنحصل على نفس النتيجة.

The important difference is that:
- `||` returns the first *truthy* value.
- `??` returns the first *defined* value.
الفرق الجوهري بينهما أن:
- `||` يرجع أول قيمة *truthy*.
- `??` يرجع أول قيمة *defined*.

This matters a lot when we'd like to treat `null/undefined` differently from `0`.
هذا مهم جدًا عندما نريد معاملة `null/undefined` بطريقة مختلفة عن `0`.

For example:
مثلًا:

```js
height = height ?? 100;
```

This sets `height` to `100` if it's not defined. But if `height` is `0`, then it remains "as is".
هذا يجعل `height` يساوي `100` إذا لم يعرف. ولكن إذا كان `height` يساوي `0` سيبقى كما هو.

Let's compare it with `||`:
لنقارنه مع `||`:

```js run
let height = 0;
Expand All @@ -56,62 +56,62 @@ alert(height || 100); // 100
alert(height ?? 100); // 0
```

Here, `height || 100` treats zero height as unset, same as `null`, `undefined` or any other falsy value, depeding on use cases that may be incorrect.
هنا `height || 100` تعامل الصفر مثل `null`, `undefined` أو أي قيمة falsy أخرىوهذا قد لا يكون صحيح أحيانًا.

The `height ?? 100` returns `100` only if `height` is exactly `null` or `undefined`.
ولكن `height ?? 100` ترجع `100` إذا كان فقط `height` يساوي تمامًا `null` أو `undefined`.

## Precedence
## الأولوية

The precedence of the `??` operator is rather low: `7` in the [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table).
أولوية المعامل `??` هي قليلة: `7` وتساوي [MDN جدول](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table).

That's lower than most operators and a bit higher than `=` and `?`.
هذا أقل من معظم المعاملات وأكبر بقليل من `=` و `?`.

So if we need to use `??` in a complex expression, then consider adding parentheses:
لذلك إذا أردنا استخدام `??` في تعبيرات معقدة نقوم بإضافة أقواس:

```js run
let height = null;
let width = null;

// important: use parentheses
// مهم: استخدم الأقواس
let area = (height ?? 100) * (width ?? 50);

alert(area); // 5000
```

Otherwise, if we omit parentheses, then `*` has the higher precedence and would run first. That would be the same as:
إذا لم نستخدم الأقواس فإن `*` له أولوية أعلى وسينفذ أولًا كأننا كتبنا:

```js
// not correct
// غير صحيح
let area = height ?? (100 * width) ?? 50;
```

There's also a related language-level limitation. Due to safety reasons, it's forbidden to use `??` together with `&&` and `||` operators.
هناك أيضًا قيود لغوية. لأسباب أمنية لا يمكن استخدام `??` مع `&&` أو `||`.

The code below triggers a syntax error:
هذا سينتج خطأ لغوي:

```js run
let x = 1 && 2 ?? 3; // Syntax error
```

The limitation is surely debatable, but for some reason it was added to the language specification.
هذا القيد قد لا يبدو منطقيًا ولكن لبعض الأسباب تم إضافته للغة.

Use explicit parentheses to fix it:
استخدم الأقواس لتجنب الخطأ:

```js run
let x = (1 && 2) ?? 3; // Works
let x = (1 && 2) ?? 3; // تعمل دون مشاكل
alert(x); // 2
```

## Summary
## ملخص

- The nullish coalescing operator `??` provides a short way to choose a "defined" value from the list.
- معامل حذف null `??` يقدم طريقة مختصرة لإختيار أول قيمة معرفة من قائمة قيم.

It's used to assign default values to variables:
يستخدم لوضع قيم افتراضية للمتغيرات:

```js
// set height=100, if height is null or undefined
// اجعل height=100 إذا كان null أو undefined
height = height ?? 100;
```

- The operator `??` has a very low precedence, a bit higher than `?` and `=`.
- It's forbidden to use it with `||` or `&&` without explicit parentheses.
- المعامل `??` لديه أولوية قليلة جدًا لكن أعلة قليلًا من `?` و `=`.
- يمنع استخدامه مع `||` أو `&&` بدون أقواس.
14 changes: 7 additions & 7 deletions 1-js/02-first-steps/13-while-for/1-loop-last-value/solution.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The answer: `1`.
الإجابة: `1`.

```js run
let i = 3;
Expand All @@ -8,18 +8,18 @@ while (i) {
}
```

Every loop iteration decreases `i` by `1`. The check `while(i)` stops the loop when `i = 0`.
كل تكرار يقوم بتقليل قيمة `i` بمقدار `1`. وتقوم `while(i)` بإيقاف الحلقة عندما `i = 0`.

Hence, the steps of the loop form the following sequence ("loop unrolled"):
وهكذا تكون الخطوات كالتالي:

```js
let i = 3;

alert(i--); // shows 3, decreases i to 2
alert(i--); // عرض 3, تقليل i إلى 2

alert(i--) // shows 2, decreases i to 1
alert(i--) // عرض 2, تقليل i إلى 1

alert(i--) // shows 1, decreases i to 0
alert(i--) // عرض 1, تقليل i إلى 0

// done, while(i) check stops the loop
// تم, while(i) تتوقف الحلقة
```
6 changes: 3 additions & 3 deletions 1-js/02-first-steps/13-while-for/1-loop-last-value/task.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
importance: 3
الأهمية: 3

---

# Last loop value
# آخر قيمة للحلقة

What is the last value alerted by this code? Why?
ما هي آخر قيمة سيتم عرضها ؟ ولماذا ؟

```js
let i = 3;
Expand Down
22 changes: 11 additions & 11 deletions 1-js/02-first-steps/13-while-for/2-which-value-while/solution.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
The task demonstrates how postfix/prefix forms can lead to different results when used in comparisons.
السؤال يوضح كيف يمكن للصيغ postfix/prefix أن تؤدي إلى نتائج مختلفة عندما تستخدم للمقارنة.

1. **From 1 to 4**
1. **من 1 إلى 4**

```js run
let i = 0;
while (++i < 5) alert( i );
```

The first value is `i = 1`, because `++i` first increments `i` and then returns the new value. So the first comparison is `1 < 5` and the `alert` shows `1`.
أول قيمة هي `i = 1` لأن `++i` أولًا تزيد `i` ثم تقوم بإرجاع القيمة الجديدة. لذلك فإن أول عملية مقارنة هي `1 < 5` ويقوم `alert` بعرض `1`.

Then follow `2, 3, 4…` -- the values show up one after another. The comparison always uses the incremented value, because `++` is before the variable.
ثم يتبع ب `2, 3, 4…` -- واحدًا بعد الآخر. المقارنة دائما تستخدم القيمة بعد الزيادة لأن `++` قبل المتغير.

Finally, `i = 4` is incremented to `5`, the comparison `while(5 < 5)` fails, and the loop stops. So `5` is not shown.
2. **From 1 to 5**
أخيرًا `i = 4`تزيد إلى `5` والمقارنة `while(5 < 5)` تفشل وتتوقف الحلقة. لذلك لا يتم عرض `5` .
2. **من 1 إلى 5**

```js run
let i = 0;
while (i++ < 5) alert( i );
```

The first value is again `i = 1`. The postfix form of `i++` increments `i` and then returns the *old* value, so the comparison `i++ < 5` will use `i = 0` (contrary to `++i < 5`).
أول قيمة هي `i = 1`. صيغة postfix `i++` تزيد `i` وترجع القيمة القديمة ولذلك تكون المقارنة `i++ < 5` تستخدم `i = 0` (على العكس من `++i < 5`).

But the `alert` call is separate. It's another statement which executes after the increment and the comparison. So it gets the current `i = 1`.
ولكن استدعاء `alert` منفصل. فهو ينفذ بعد الزيادة والمقارنة. لذلك يحصل على القيمة الحالية `i = 1`.

Then follow `2, 3, 4…`
ثم يتبعه `2, 3, 4…`

Let's stop on `i = 4`. The prefix form `++i` would increment it and use `5` in the comparison. But here we have the postfix form `i++`. So it increments `i` to `5`, but returns the old value. Hence the comparison is actually `while(4 < 5)` -- true, and the control goes on to `alert`.
لنتوقف عند `i = 4`. صيغة prefix `++i` تزيدها وتستخدم `5` في المقارنة. لكن postfix `i++` تزيد `i` إلى `5`وترجع القيمة القديمة. فتكون المقارنة `while(4 < 5)` -- true وينفذ `alert`.

The value `i = 5` is the last one, because on the next step `while(5 < 5)` is false.
قيمة `i = 5` هي آخر قيمة لأن في الخطوة التالية `while(5 < 5)` تكون false.
12 changes: 6 additions & 6 deletions 1-js/02-first-steps/13-while-for/2-which-value-while/task.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
importance: 4
الأهمية: 4

---

# Which values does the while loop show?
# ما القيم التي ستعرضها الحلقة ؟

For every loop iteration, write down which value it outputs and then compare it with the solution.
في كل تكرار قم بكتابة القيمة التي سيتم عرضها وقارن إجابتك مع الحل.

Both loops `alert` the same values, or not?
هل تقوم كلتا الحلقتين بعرض نفس القيم أم لا ؟

1. The prefix form `++i`:
1. صيغة prefix `++i`:

```js
let i = 0;
while (++i < 5) alert( i );
```
2. The postfix form `i++`
2. صيغة postfix `i++`

```js
let i = 0;
Expand Down
14 changes: 7 additions & 7 deletions 1-js/02-first-steps/13-while-for/3-which-value-for/solution.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
**The answer: from `0` to `4` in both cases.**
**الإجابة: من `0` إلى `4` في كلتا الحالتين.**

```js run
for (let i = 0; i < 5; ++i) alert( i );

for (let i = 0; i < 5; i++) alert( i );
```

That can be easily deducted from the algorithm of `for`:
يمكن إيجاد الحل بسهولة من خوارزمية `for`:

1. Execute once `i = 0` before everything (begin).
2. Check the condition `i < 5`
3. If `true` -- execute the loop body `alert(i)`, and then `i++`
1. تنفذ لمرة واحدة `i = 0` قبل أي شئ (begin).
2. تفحص الشرط `i < 5`
3. لو `true` -- تنفذل الأمر `alert(i)` ثم `i++`

The increment `i++` is separated from the condition check (2). That's just another statement.
الزيادة `i++` منفصلة عن فحص الشرط (2). هي فقط أمر آخر.

The value returned by the increment is not used here, so there's no difference between `i++` and `++i`.
لا يتم استخدام القيمة الراجعة من عملية الزيادة لذلك لا فرق بين `i++` و `++i`.
12 changes: 6 additions & 6 deletions 1-js/02-first-steps/13-while-for/3-which-value-for/task.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
importance: 4
الأهمية: 4

---

# Which values get shown by the "for" loop?
# ما القيم التي ستعرض بواسطة الحلقة "for"?

For each loop write down which values it is going to show. Then compare with the answer.
قم بكتابة القيمة التي ستعرض في كل كل حلقة وقارنها بالحل.

Both loops `alert` same values or not?
هل ستقوم كلتا الحلقتين بعرض نفس القيم أم لا ؟

1. The postfix form:
1. صيغة postfix:

```js
for (let i = 0; i < 5; i++) alert( i );
```
2. The prefix form:
2. صيغة prefix:

```js
for (let i = 0; i < 5; ++i) alert( i );
Expand Down
2 changes: 1 addition & 1 deletion 1-js/02-first-steps/13-while-for/4-for-even/solution.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ for (let i = 2; i <= 10; i++) {
}
```

We use the "modulo" operator `%` to get the remainder and check for the evenness here.
نستخدم معامل باقي القسمة `%` لإيجاد باقي القسمة وفحص إذا كان الرقم زوجي.
6 changes: 3 additions & 3 deletions 1-js/02-first-steps/13-while-for/4-for-even/task.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
importance: 5
الأهمية: 5

---

# Output even numbers in the loop
# قم بعرض الأرقام الزوجية داخل حلقة تكرارية

Use the `for` loop to output even numbers from `2` to `10`.
استخدم حلقة `for` لعرض الأرقام الزوجية من `2` إلى `10`.

[demo]
6 changes: 3 additions & 3 deletions 1-js/02-first-steps/13-while-for/5-replace-for-while/task.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
importance: 5
الأهمية: 5

---

# Replace "for" with "while"
# استبدل "for" ب "while"

Rewrite the code changing the `for` loop to `while` without altering its behavior (the output should stay same).
اعد كتابة الكود التالي وقم بتبديل حلقة `for` بحلقة `while` دون تغيير الخرج.

```js run
for (let i = 0; i < 3; i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
let num;

do {
num = prompt("Enter a number greater than 100?", 0);
num = prompt("ادخل رقم أكبر من 100?", 0);
} while (num <= 100 && num);
```

The loop `do..while` repeats while both checks are truthy:
حلقة `do..while` تكرر طالما الشرطين محققين:

1. The check for `num <= 100` -- that is, the entered value is still not greater than `100`.
2. The check `&& num` is false when `num` is `null` or a empty string. Then the `while` loop stops too.
1. شرط `num <= 100` -- أن القيمة لا تزال أقل من أو تساوي `100`.
2. والشرط `&& num` يكون false عندما `num` تكون `null` أو نص فارغ. وهنا تتوقف حلقة `while`.

P.S. If `num` is `null` then `num <= 100` is `true`, so without the 2nd check the loop wouldn't stop if the user clicks CANCEL. Both checks are required.
لاحظ أن إذا كان `num` يساوي `null` يكون الشرط `num <= 100` يساوي `true` لذلك لن تتوقف عملية الإدخال إذا قام المستخدم بإلغائها فكلا الشرطين مطلوب.
10 changes: 5 additions & 5 deletions 1-js/02-first-steps/13-while-for/6-repeat-until-correct/task.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
importance: 5
الأهمية: 5

---

# Repeat until the input is correct
# تكرار حتى الإدخال الصحيح

Write a loop which prompts for a number greater than `100`. If the visitor enters another number -- ask them to input again.
أكتب حلقة تطلب رقم أكبر من `100`. إذا قام المستخدم بإدخال رقم آخر اسأله مرة أخرى.

The loop must ask for a number until either the visitor enters a number greater than `100` or cancels the input/enters an empty line.
يجب أن تظل تسأل المستخدم حتى يدخل رقم أكبر من `100` أو يوقف الإدخال أو يدخل نص فارغ.

Here we can assume that the visitor only inputs numbers. There's no need to implement a special handling for a non-numeric input in this task.
هنا نفترض أن المستخدم يدخل فقط أرقام فلا داعي للتأكد من القيم الغير رقمية.

[demo]
Loading