diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 000000000..490051876
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+github: iliakan
diff --git a/.gitignore b/.gitignore
index 6f90fd190..1a71fb7c8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,4 @@ sftp-config.json
Thumbs.db
+/svgs
\ No newline at end of file
diff --git a/1-js/01-getting-started/1-intro/article.md b/1-js/01-getting-started/1-intro/article.md
index c048430b3..d6d20fb5f 100644
--- a/1-js/01-getting-started/1-intro/article.md
+++ b/1-js/01-getting-started/1-intro/article.md
@@ -49,9 +49,17 @@
تعتÙ
د ÙØ¯Ø±Ø§Øª Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت بشÙÙ ÙØ¨Ùر عÙÙ Ø§ÙØ¨Ùئة Ø§ÙØªÙ تعÙ
Ù Ø¨ÙØ§. عÙ٠سبÙ٠اÙÙ
Ø«Ø§Ù Ø ÙØ¯Ø¹Ù
[ÙÙØ¯.ج٠إس](https://ar.wikipedia.org/wiki/ÙÙØ¯.جÙ_إس)
اÙÙØ¸Ø§Ø¦Ù Ø§ÙØªÙ تسÙ
Ø ÙØ¬Ø§Ùا Ø³ÙØ±Ùبت Ø¨ÙØ±Ø§Ø¡Ø© / ÙØªØ§Ø¨Ø© Ù
ÙÙØ§Øª Ø¹Ø´ÙØ§Ø¦ÙØ© Ø ÙØªÙÙÙØ° Ø·ÙØ¨Ø§Øª Ø§ÙØ´Ø¨ÙØ©Ø Ø¥ÙØ®.
+<<<<<<< HEAD
ÙÙ
ÙÙ ÙØ¬Ø§Ùا Ø³ÙØ±Ùبت Ù٠اÙÙ
ØªØµÙØ اÙÙÙØ§Ù
بÙÙ Ù
ا ÙØªØ¹Ù٠بÙ
Ø¹Ø§ÙØ¬Ø© ØµÙØØ§Øª اÙÙÙØ¨ ÙØ§ÙØªÙØ§Ø¹Ù Ù
ع اÙÙ
ستخدÙ
ÙØ®Ø§Ø¯Ù
اÙÙÙØ¨.
عÙ٠سبÙ٠اÙÙ
Ø«Ø§Ù Ø ÙÙ
ÙÙ ÙØ¬Ø§Ùا Ø³ÙØ±Ùبت Ù٠اÙÙ
ØªØµÙØ:
+=======
+- [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine)) -- in Chrome, Opera and Edge.
+- [SpiderMonkey](https://en.wikipedia.org/wiki/SpiderMonkey) -- in Firefox.
+- ...There are other codenames like "Chakra" for IE, "JavaScriptCore", "Nitro" and "SquirrelFish" for Safari, etc.
+
+The terms above are good to remember because they are used in developer articles on the internet. We'll use them too. For instance, if "a feature X is supported by V8", then it probably works in Chrome, Opera and Edge.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
- Ø¥Ø¶Ø§ÙØ© HTML Ø¬Ø¯ÙØ¯ Ø¥ÙÙ Ø§ÙØµÙØØ© Ø ÙØªØºÙÙØ± اÙÙ
ØØªÙÙ Ø§ÙØØ§ÙÙ Ø ÙØªØ¹Ø¯ÙÙ Ø§ÙØªØµØ§Ù
ÙÙ
.
- Ø§ÙØ±Ø¯ عÙÙ ØªÙØ§Ø¹Ùات اÙÙ
ستخدÙ
Ø ÙØ§ÙتشغÙ٠عÙÙ ÙÙØ±Ø§Øª اÙÙØ£Ø±Ø© Ø ÙØØ±ÙØ§Øª اÙÙ
ؤشر Ø ÙØ§Ùضغط عÙ٠اÙÙ
ÙØ§ØªÙØ.
@@ -61,17 +69,28 @@
## Ù
ا Ø§ÙØ°Ù ÙØ§ ÙÙ
ÙÙ ÙØ¬Ø§Ùا Ø³ÙØ±Ùبت Ù٠اÙÙ
ØªØµÙØ ÙØ¹ÙÙØ
+<<<<<<< HEAD
Ø¥Ù
ÙØ§ÙÙØ§Øª Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت Ù٠اÙÙ
ØªØµÙØ Ù
ØØ¯Ùدة Ù
Ù Ø£Ø¬Ù Ø³ÙØ§Ù
Ø© اÙÙ
ستخدÙ
. اÙÙØ¯Ù ÙÙ Ù
ÙØ¹ ØµÙØØ© ÙÙØ¨ Ø´Ø±ÙØ±Ø© Ù
٠اÙÙØµÙ٠إÙ٠اÙÙ
عÙÙÙ
ات Ø§ÙØ®Ø§ØµØ© Ø£Ù Ø§ÙØ¥Ø¶Ø±Ø§Ø± Ø¨Ø¨ÙØ§Ùات اÙÙ
ستخدÙ
.
+=======
+1. The engine (embedded if it's a browser) reads ("parses") the script.
+2. Then it converts ("compiles") the script to machine code.
+3. And then the machine code runs, pretty fast.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù
٠أÙ
Ø«ÙØ© ÙØ°Ù اÙÙÙÙØ¯:
- Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت عÙÙ ØµÙØØ© اÙÙÙØ¨ ÙØ¯ ÙØ§ ØªÙØ±Ø£/ØªÙØªØ¨ Ù
ÙÙØ§Øª Ø¹Ø´ÙØ§Ø¦ÙØ© عÙ٠اÙÙØ±Øµ Ø§ÙØµÙب Ø£Ù ØªÙØ³Ø®Ùا أ٠تÙÙØ° براÙ
ج. ÙÙØ³ ÙØ¯ÙÙØ§ ÙØµÙÙ Ù
باشر Ø¥ÙÙ ÙØ¸Ø§Ø¦Ù ÙØ¸Ø§Ù
Ø§ÙØªØ´ØºÙÙ.
+<<<<<<< HEAD
تسÙ
Ø Ø§ÙÙ
ØªØµÙØØ§Øª Ø§ÙØØ¯ÙØ«Ø© ÙÙ Ø¨Ø§ÙØ¹Ù
Ù Ù
ع اÙÙ
ÙÙØ§Øª Ø ÙÙÙ٠اÙÙØµÙÙ Ù
ØØ¯Ùد ÙÙØªÙ
تÙÙÙØ±Ù ÙÙØ· إذا ÙØ§Ù
اÙÙ
ستخدÙ
بإجراءات Ù
عÙÙØ© Ø Ù
ث٠"Ø¥Ø³ÙØ§Ø·" Ù
ÙÙ ÙÙ ÙØ§Ùذة اÙÙ
ØªØµÙØ Ø£Ù ØªØØ¯Ùد٠عبر Ø¹ÙØ§Ù
Ø© ``.
+=======
+Modern JavaScript is a "safe" programming language. It does not provide low-level access to memory or the CPU, because it was initially created for browsers which do not require it.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ§Ù طر٠ÙÙØªÙاع٠Ù
ع اÙÙØ§Ù
ÙØ±Ø§ / اÙÙ
ÙÙØ±ÙÙÙÙ ÙØ§ÙØ£Ø¬ÙØ²Ø© Ø§ÙØ£Ø®Ø±Ù Ø ÙÙÙÙØ§ ØªØªØ·ÙØ¨ إذÙÙØ§ ØµØ±ÙØÙØ§ Ù
٠اÙÙ
ستخدÙ
. ÙØ°ÙÙ ÙØ¯ ÙØ§ تعÙ
Ù Ø§ÙØµÙØØ© Ø§ÙØªÙ تÙ
تÙ
ÙÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙÙÙØ§ بشÙÙ Ø®Ù٠عÙ٠تÙ
ÙÙÙ ÙØ§Ù
ÙØ±Ø§ اÙÙÙØ¨ ÙÙ
Ø±Ø§ÙØ¨Ø© اÙÙ
ÙØ§Ø·Ù اÙÙ
ØÙطة ÙØ¥Ø±Ø³Ø§Ù اÙÙ
عÙÙÙ
ات Ø¥ÙÙ [آ٠آس Ø£ÙÙ](https://ar.wikipedia.org/wiki/ÙÙØ§ÙØ©_Ø§ÙØ£Ù
Ù_اÙÙÙÙ
Ù_Ø§ÙØ£Ù
رÙÙÙØ©)
-بشÙ٠عاÙ
ÙØ§ ØªØ¹Ø±Ù Ø¹ÙØ§Ù
ات Ø§ÙØªØ¨ÙÙØ¨ / اÙÙÙØ§Ùذ اÙÙ
ختÙÙØ© ØÙÙ Ø¨Ø¹Ø¶ÙØ§ Ø§ÙØ¨Ø¹Ø¶. Ù٠بعض Ø§ÙØ£ØÙا٠ÙÙØ¹ÙÙ٠ذÙÙØ عÙ٠سبÙ٠اÙÙ
Ø«Ø§Ù Ø¹ÙØ¯Ù
ا تستخدÙ
Ø¥ØØ¯Ù اÙÙÙØ§Ùذ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙÙØªØ اÙÙØ§Ùذة Ø§ÙØ£Ø®Ø±Ù. ÙÙÙÙ ØØªÙ ÙÙ ÙØ°Ù Ø§ÙØØ§ÙØ© Ø ÙØ¯ ÙØ§ تتÙ
ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙÙ Ø¥ØØ¯Ù Ø§ÙØµÙØØ§Øª Ù
٠اÙÙØµÙ٠إÙÙ Ø§ÙØµÙØØ© Ø§ÙØ£Ø®Ø±Ù إذا ÙØ§Ùت تأت٠Ù
Ù Ù
ÙØ§Ùع Ù
ختÙÙØ© (Ù
Ù Ù
Ø¬Ø§Ù Ø£Ù Ø¨Ø±ÙØªÙÙÙ٠أ٠Ù
ÙÙØ° Ù
ختÙÙ).
+<<<<<<< HEAD
ÙÙØ°Ø§ Ù
ا ÙØ³Ù
Ù "Ø³ÙØ§Ø³Ø© اÙÙ
صدر Ø§ÙØ£ÙØØ¯". ÙÙØªØºÙب عÙ٠ذÙÙ Ø ÙØ¬Ø¨ Ø£Ù ØªÙØ§ÙÙ *Ø§ÙØµÙØØªØ§Ù* عÙÙ ØªØ¨Ø§Ø¯Ù Ø§ÙØ¨ÙØ§ÙØ§Øª ÙØªØØªÙ٠عÙÙ ÙÙØ¯ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت خاص ÙØªØ¹Ø§Ù
Ù Ù
عÙ. Ø³ÙØºØ·Ù ذÙÙ ÙÙ Ø§ÙØ¨Ø±ÙاÙ
ج Ø§ÙØªØ¹ÙÙÙ
Ù.
ÙØ°Ø§ اÙÙÙØ¯ Ø Ù
رة Ø£Ø®Ø±Ù Ø ÙØ³ÙاÙ
Ø© اÙÙ
ستخدÙ
. ÙØ¬Ø¨ Ø£ÙØ§ تتÙ
ÙÙ ØµÙØØ© Ù
Ù `http://anysite.com` ÙØªØÙا اÙÙ
ستخدÙ
Ù
٠اÙÙØµÙ٠إÙÙ ÙØ§Ùذة Ù
ØªØµÙØ أخر٠بعÙÙØ§Ù `http://gmail.com` ÙØ³Ø±ÙØ© اÙÙ
عÙÙÙ
ات Ù
Ù ÙÙØ§Ù.
@@ -80,20 +99,63 @@

ÙØ§ ØªÙØ¬Ø¯ Ù
Ø«Ù ÙØ°Ù Ø§ÙØØ¯ÙØ¯ إذا تÙ
استخداÙ
Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت خارج اÙÙ
ØªØµÙØ Ø Ø¹Ù٠سبÙ٠اÙÙ
ثا٠عÙÙ Ø§ÙØ®Ø§Ø¯Ù
. تسÙ
Ø Ø§ÙÙ
ØªØµÙØØ§Øª Ø§ÙØØ¯ÙØ«Ø© Ø£ÙØ¶Ùا Ø§ÙØ¥Ø¶Ø§Ùات Ø§ÙØªÙ ÙØ¯ ØªØ·ÙØ¨ ØªØµØ±ÙØØ§Øª Ù
Ù
تدة.
+=======
+In-browser JavaScript can do everything related to webpage manipulation, interaction with the user, and the webserver.
+
+For instance, in-browser JavaScript is able to:
+
+- Add new HTML to the page, change the existing content, modify styles.
+- React to user actions, run on mouse clicks, pointer movements, key presses.
+- Send requests over the network to remote servers, download and upload files (so-called [AJAX](https://en.wikipedia.org/wiki/Ajax_(programming)) and [COMET](https://en.wikipedia.org/wiki/Comet_(programming)) technologies).
+- Get and set cookies, ask questions to the visitor, show messages.
+- Remember the data on the client-side ("local storage").
+
+## What CAN'T in-browser JavaScript do?
+
+JavaScript's abilities in the browser are limited to protect the user's safety. The aim is to prevent an evil webpage from accessing private information or harming the user's data.
+
+Examples of such restrictions include:
+
+- JavaScript on a webpage may not read/write arbitrary files on the hard disk, copy them or execute programs. It has no direct access to OS functions.
+
+ Modern browsers allow it to work with files, but the access is limited and only provided if the user does certain actions, like "dropping" a file into a browser window or selecting it via an `` tag.
+
+ There are ways to interact with the camera/microphone and other devices, but they require a user's explicit permission. So a JavaScript-enabled page may not sneakily enable a web-camera, observe the surroundings and send the information to the [NSA](https://en.wikipedia.org/wiki/National_Security_Agency).
+- Different tabs/windows generally do not know about each other. Sometimes they do, for example when one window uses JavaScript to open the other one. But even in this case, JavaScript from one page may not access the other page if they come from different sites (from a different domain, protocol or port).
+
+ This is called the "Same Origin Policy". To work around that, *both pages* must agree for data exchange and must contain special JavaScript code that handles it. We'll cover that in the tutorial.
+
+ This limitation is, again, for the user's safety. A page from `http://anysite.com` which a user has opened must not be able to access another browser tab with the URL `http://gmail.com`, for example, and steal information from there.
+- JavaScript can easily communicate over the net to the server where the current page came from. But its ability to receive data from other sites/domains is crippled. Though possible, it requires explicit agreement (expressed in HTTP headers) from the remote side. Once again, that's a safety limitation.
+
+
+
+Such limitations do not exist if JavaScript is used outside of the browser, for example on a server. Modern browsers also allow plugins/extensions which may ask for extended permissions.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## Ù
ا Ø§ÙØ°Ù ÙØ¬Ø¹Ù Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØ±ÙØ¯ÙØ§Ø
ÙÙØ§Ù عÙÙ Ø§ÙØ£ÙÙ *Ø«ÙØ§Ø«Ø©* Ø£Ø´ÙØ§Ø¡ رائعة ØÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت:
```compare
+<<<<<<< HEAD
+ ØªÙØ§Ù
٠تاÙ
Ù
ع HTML / CSS.
+ Ø§ÙØ£Ø´Ùاء Ø§ÙØ¨Ø³Ùطة تتÙ
ببساطة.
+ Ù
دعÙÙ
Ù
Ù ÙØ¨Ù جÙ
ÙØ¹ اÙÙ
ØªØµÙØØ§Øª Ø§ÙØ±Ø§Ø¦Ø¯Ø© ÙØªÙ
ÙÙÙ٠تÙÙØ§Ø¦Ùا.
+=======
++ Full integration with HTML/CSS.
++ Simple things are done simply.
++ Supported by all major browsers and enabled by default.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت Ù٠تÙÙÙØ© اÙÙ
ØªØµÙØ اÙÙØÙØ¯Ø© Ø§ÙØªÙ تجÙ
ع بÙÙ ÙØ°Ù Ø§ÙØ£Ø´Ùاء Ø§ÙØ«Ùاثة.
+<<<<<<< HEAD
ÙØ°Ø§ Ù
ا ÙØ¬Ø¹Ù Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØ±ÙØ¯ÙØ§. ÙØ°Ø§ ÙÙ Ø§ÙØ³Ø¨Ø¨ Ù٠أÙÙØ§ Ø§ÙØ£Ø¯Ø§Ø© Ø§ÙØ£Ùثر Ø§ÙØªØ´Ø§Ø±Ùا ÙØ¥Ùشاء ÙØ§Ø¬Ùات اÙÙ
ØªØµÙØ.
+=======
+That said, JavaScript can be used to create servers, mobile applications, etc.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
ع ذÙÙØ تسÙ
Ø Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت Ø£ÙØ¶Ùا Ø¨Ø¥ÙØ´Ø§Ø¡ Ø®ÙØ§Ø¯Ù
ÙØªØ·Ø¨ÙÙØ§Øª Ø§ÙØ¬ÙØ§ÙØ Ø¥ÙØ®.
@@ -101,12 +163,17 @@
ÙØ§ ØªØªÙØ§Ø³Ø¨ اÙÙÙØ§Ø¹Ø¯ اÙÙØºÙÙØ© ÙØ¬Ø§Ùا Ø³ÙØ±Ùبت Ù
ع Ø§ØØªÙاجات Ø§ÙØ¬Ù
ÙØ¹. اÙÙØ§Ø³ اÙÙ
ختÙÙÙÙ ÙØ±ÙدÙÙ Ù
ÙØ²Ø§Øª Ù
ختÙÙØ©.
+<<<<<<< HEAD
ÙØ°Ø§ Ø£Ù
ر Ù
تÙÙØ¹ Ø ÙØ£Ù اÙÙ
Ø´Ø§Ø±ÙØ¹ ÙØ§ÙÙ
ØªØ·ÙØ¨Ø§Øª تختÙÙ Ù
٠شخص ÙØ¢Ø®Ø±.
+=======
+So, recently a plethora of new languages appeared, which are *transpiled* (converted) to JavaScript before they run in the browser.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¸ÙØ±Øª ÙÙ Ø§ÙØ¢ÙÙØ© Ø§ÙØ£Ø®Ùرة عدد ÙØ¨Ùر Ù
٠اÙÙØºØ§Øª Ø§ÙØ¬Ø¯Ùدة Ø ÙØ§Ùت٠*تÙ
تØÙÙÙÙØ§* Ø¥ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØ¨Ù تشغÙÙÙØ§ Ù٠اÙÙ
ØªØµÙØ.
Ø§ÙØ£Ø¯Ùات Ø§ÙØØ¯ÙØ«Ø© ØªØ¬Ø¹Ù Ø§ÙØªØ±Ø¬Ù
Ø© Ø³Ø±ÙØ¹Ø© ÙØ´ÙØ§ÙØ© ÙÙØºØ§ÙØ© Ø Ù
Ù
ا ÙØ³Ù
Ø ÙÙÙ
Ø·ÙØ±ÙÙ Ù٠اÙÙØ§Ùع Ø¨Ø§ÙØªØ´ÙÙØ± Ø¨ÙØºØ© Ø£Ø®Ø±Ù ÙØªØÙÙÙÙØ§ تÙÙØ§Ø¦ÙÙØ§ "Ø®Ù٠اÙÙÙØ§ÙÙØ³".
+<<<<<<< HEAD
Ø£Ù
Ø«ÙØ© عÙÙ ÙØ°Ù اÙÙØºØ§Øª:
- [ÙÙÙÙ Ø³ÙØ±Ùبت](http://coffeescript.org/) ÙÙ "Ø³ÙØ± ÙØÙÙ" ÙØ¬Ø§Ùا Ø³ÙØ±Ùبت. Ø¥ÙÙ ÙÙØ¯Ù
Ø¨ÙØ§Ø¡ جÙ
Ù Ø£ÙØµØ± Ø Ù
Ù
ا ÙØ³Ù
Ø ÙÙØ§ Ø¨ÙØªØ§Ø¨Ø© ÙÙØ¯ Ø£ÙØ«Ø± ÙØ¶ÙØÙا ÙØ¯ÙØ©. عادة ØÙ
Ø·ÙØ±Ù Ø±ÙØ¨Ù ÙØØ¨ÙÙÙØ§.
@@ -115,11 +182,27 @@
- [دارت](https://www.dartlang.org/) ÙÙ ÙØºØ© ÙØ§Ø¦Ù
Ø© Ø¨Ø°Ø§ØªÙØ§ ÙÙØ§ Ù
ØØ±ÙÙØ§ Ø§ÙØ®Ø§Øµ Ø§ÙØ°Ù ÙØ¹Ù
Ù ÙÙ Ø¨ÙØ¦Ø§Øª ØºÙØ± اÙÙ
ØªØµÙØ (Ù
ث٠تطبÙÙØ§Øª اÙÙØ§ØªÙ اÙÙ
ØÙ
ÙÙ) Ø ÙÙÙÙ ÙÙ
ÙÙ Ø£ÙØ¶Ùا تØÙÙÙÙØ§ Ø¥ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت. Ù
٠تطÙÙØ± Ø¬ÙØ¬Ù.
- [Ø¨Ø±ÙØ«ÙÙ](https://brython.info/) ÙÙ Ù
ØÙÙ Ù
Ù Ø¨Ø§ÙØ«Ù٠إÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت Ù Ø§ÙØ°Ù ÙÙ
ÙÙÙ Ù
Ù ÙØªØ§Ø¨Ø© Ø§ÙØªØ·Ø¨ÙÙØ§Øª Ø¨ÙØºØ© Ø¨Ø§ÙØ«Ù٠بشÙÙ ÙØ§Ù
٠بدÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت.
- [ÙÙØªÙÙ](https://kotlinlang.org/docs/reference/js-overview.html) ÙÙ ÙØºØ© برÙ
جة ØØ¯Ùثة ÙÙ
ÙØ¬Ø²Ø© ÙØ¢Ù
ÙØ© ÙÙ
ÙÙÙØ§ Ø§Ø³ØªÙØ¯Ø§Ù اÙÙ
ØªØµÙØ Ø£Ù ÙÙØ¯.
+=======
+- [CoffeeScript](https://coffeescript.org/) is "syntactic sugar" for JavaScript. It introduces shorter syntax, allowing us to write clearer and more precise code. Usually, Ruby devs like it.
+- [TypeScript](https://www.typescriptlang.org/) is concentrated on adding "strict data typing" to simplify the development and support of complex systems. It is developed by Microsoft.
+- [Flow](https://flow.org/) also adds data typing, but in a different way. Developed by Facebook.
+- [Dart](https://www.dartlang.org/) is a standalone language that has its own engine that runs in non-browser environments (like mobile apps), but also can be transpiled to JavaScript. Developed by Google.
+- [Brython](https://brython.info/) is a Python transpiler to JavaScript that enables the writing of applications in pure Python without JavaScript.
+- [Kotlin](https://kotlinlang.org/docs/reference/js-overview.html) is a modern, concise and safe programming language that can target the browser or Node.
+
+There are more. Of course, even if we use one of these transpiled languages, we should also know JavaScript to really understand what we're doing.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ§Ù Ø£ÙØ«Ø±. Ø¨Ø§ÙØ·Ø¨Ø¹ Ø ØØªÙ Ù٠استخدÙ
ÙØ§ Ø¥ØØ¯Ù اÙÙØºØ§Øª اÙÙ
ترجÙ
Ø© Ø ÙØ¬Ø¨ Ø£Ù ÙØ¹Ø±Ù Ø£ÙØ¶Ùا Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙÙÙÙ
Ù
ا ÙÙÙÙ
ب٠ØÙÙØ§.
+<<<<<<< HEAD
## Ù
ÙØ®Øµ
- تÙ
Ø¥ÙØ´Ø§Ø¡ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙÙ Ø§ÙØ¨Ø¯Ø§ÙØ© ÙÙØºØ© ÙÙÙ
ØªØµÙØ ÙÙØ· Ø ÙÙÙÙÙØ§ ØªÙØ³ØªØ®Ø¯Ù
Ø§ÙØ¢Ù ÙÙ Ø§ÙØ¹Ø¯Ùد Ù
Ù Ø§ÙØ¨Ùئات Ø§ÙØ£Ø®Ø±Ù Ø£ÙØ¶Ùا.
- تتÙ
تع Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت اÙÙÙÙ
بÙ
ÙØ§ÙØ© ÙØ±Ùدة Ø¨Ø§Ø¹ØªØ¨Ø§Ø±ÙØ§ ÙØºØ© اÙÙ
ØªØµÙØ Ø§ÙØ£Ùثر استخداÙ
ÙØ§ Ù
ع ØªÙØ§Ù
ÙÙØ§ Ø§ÙØªØ§Ù
Ù
ع HTML / CSS.
-- ÙÙØ§Ù Ø§ÙØ¹Ø¯Ùد Ù
٠اÙÙØºØ§Øª Ø§ÙØªÙ ÙØªÙ
"تØÙÙÙÙØ§" Ø¥ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØªÙÙØ± Ù
ÙØ²Ø§Øª Ù
عÙÙØ©. ÙÙØµÙ بإÙÙØ§Ø¡ ÙØ¸Ø±Ø© عÙÙÙÙ
Ø Ø¹ÙÙ Ø§ÙØ£ÙÙ ÙÙØªØ±Ø© ÙØ¬Ùزة Ø Ø¨Ø¹Ø¯ Ø¥ØªÙØ§Ù Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت.
\ No newline at end of file
+- ÙÙØ§Ù Ø§ÙØ¹Ø¯Ùد Ù
٠اÙÙØºØ§Øª Ø§ÙØªÙ ÙØªÙ
"تØÙÙÙÙØ§" Ø¥ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØªÙÙØ± Ù
ÙØ²Ø§Øª Ù
عÙÙØ©. ÙÙØµÙ بإÙÙØ§Ø¡ ÙØ¸Ø±Ø© عÙÙÙÙ
Ø Ø¹ÙÙ Ø§ÙØ£ÙÙ ÙÙØªØ±Ø© ÙØ¬Ùزة Ø Ø¨Ø¹Ø¯ Ø¥ØªÙØ§Ù Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت.
+=======
+- JavaScript was initially created as a browser-only language, but it is now used in many other environments as well.
+- Today, JavaScript has a unique position as the most widely-adopted browser language, fully integrated with HTML/CSS.
+- There are many languages that get "transpiled" to JavaScript and provide certain features. It is recommended to take a look at them, at least briefly, after mastering JavaScript.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/01-getting-started/2-manuals-specifications/article.md b/1-js/01-getting-started/2-manuals-specifications/article.md
index 4310dd262..d2e32e69d 100644
--- a/1-js/01-getting-started/2-manuals-specifications/article.md
+++ b/1-js/01-getting-started/2-manuals-specifications/article.md
@@ -2,7 +2,11 @@
ÙØ°Ø§ اÙÙØªØ§Ø¨ ÙÙ _Ø¯ÙØ±Ø© تعÙÙÙ
ÙØ©_. ÙÙØ¯Ù اÙ٠تعÙÙÙ
٠اÙÙØºÙ ØªØ¯Ø±ÙØ¬Ùا. Ù ÙÙ٠إذا ÙÙØª عÙ٠عÙÙ
Ø¨Ø§ÙØ£Ø³Ø§Ø³Ùات ÙØ³ÙÙ ØªØØªØ§Ø¬ Ø¥ÙÙ Ù
صدر آخر.
+<<<<<<< HEAD
## اÙÙØµÙ
+=======
+This book is a *tutorial*. It aims to help you gradually learn the language. But once you're familiar with the basics, you'll need other resources.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
[ÙØµÙ The ECMA-262](https://www.ecma-international.org/publications/standards/Ecma-262.htm) ÙØØªÙ٠عÙ٠اÙÙ
عÙÙÙ
ات Ø§ÙØ£Ùثر عÙ
ÙØ§Ù ÙØªÙصÙÙØ§Ù ÙØ±Ø³Ù
ÙØ©Ù Ø¹Ù Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت. ÙÙ٠تÙÙÙ
بتعرÙ٠اÙÙØºØ©.
@@ -10,7 +14,11 @@
ÙØ³Ø®Ø© ÙØµÙ Ø¬Ø¯ÙØ¯Ø© ØªÙØµØ¯Ø± Ù٠عاÙ
. ÙÙÙ
ا بÙÙ ÙØ°Ù Ø§ÙØ¥ØµØ¯Ø§Ø±Ø§ØªØ آخر Ù
Ø³ÙØ¯Ø© ÙØµÙ ØªÙØ¬Ø¯ ÙÙ .
+<<<<<<< HEAD
ÙÙÙ ØªÙØ±Ø£ ع٠خصائص Ø§ÙØªØ·Ùر Ø§ÙØØ§Ø¯ Ø§ÙØ¬Ø¯ÙØ¯Ø Ø¨Ù
ا Ù٠ذÙÙ "اÙÙ
عاÙÙØ± Ø§ÙØªÙØ±ÙØ¨ÙØ©" (Ù
ا ÙØ³Ù
Ù "اÙÙ
رØÙØ© 3")Ø Ø§ÙØ¸Ø± ÙÙÙ
ÙØªØ±ØØ§Øª ÙÙ .
+=======
+A new specification version is released every year. Between these releases, the latest specification draft is at .
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø£ÙØ¶Ø§ÙØ Ø¥Ø°Ø§ ÙÙØª ØªØ·ÙØ± Ù
٠أج٠اÙÙ
ØªØµÙØØ Ø¥Ø°Ø§ ÙÙØ§Ù Ù
ÙØ§ØµÙات أخر٠Ù
Ø´Ù
ÙÙØ© ÙÙ [Ø§ÙØ¬Ø²Ø¡ Ø§ÙØ«Ø§ÙÙ](info:browser-environment) Ù
Ù Ø§ÙØ¯Ùرة Ø§ÙØªØ¹ÙÙÙ
ÙØ©.
@@ -20,18 +28,31 @@
ÙÙ
ÙÙ Ø£Ù ØªØ¬Ø¯ÙØ§ ÙÙ .
+<<<<<<< HEAD
Ø£ÙØ¶Ø§ÙØ ØºØ§ÙØ¨Ø§Ù Ù
ا ÙÙÙÙ Ù
Ù Ø§ÙØ£Ùض٠استخداÙ
Ø§ÙØ¨ØØ« عبر Ø§ÙØ¥ÙØªØ±ÙØª Ø¨Ø¯ÙØ§Ù Ù
٠ذÙÙ. ÙÙØ· استخدÙ
"[Ù
ØµØ·ÙØ] MDN" ÙÙØ¥Ø³ØªØ¹ÙاÙ
Ø Ù
Ø«Ø§Ù ÙØªØ¨ØØ« Ø¹Ù Ø¯Ø§ÙØ© `parseInt`.
+=======
+ You can find it at .
+
+Although, it's often best to use an internet search instead. Just use "MDN [term]" in the query, e.g. to search for the `parseInt` function.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## جدÙÙ Ø§ÙØªÙاÙÙ
Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØºØ© ÙÙ Ø³ÙØ§Ù Ù
ØªØ·ÙØ±Ø تضا٠إÙÙÙØ§ خصائص Ø¬Ø¯ÙØ¯Ø© Ø¨Ø§ÙØªØ¸Ø§Ù
.
+<<<<<<< HEAD
ÙØªÙÙÙØÙÙÙÙÙ Ù
Ù Ø§ÙØ¯Ø¹Ù
Ù
ا بÙ٠اÙÙ
ØªØµÙØØ§Øª ÙØ§ÙÙ
ØØ±Ùات Ø§ÙØ£Ø®Ø±ÙØ Ø§ÙØ¸Ø±:
- - جدÙÙ Ø§ÙØ¯Ø¹Ù
ÙÙÙ Ø®Ø§ØµÙØ©Ø Ù
ثاÙ: ÙØªØ±Ù Ø£ÙÙØ§ Ù
٠اÙÙ
ØØ±Ùات ÙØ¯Ø¹Ù
Ø¯ÙØ§Ù Ø§ÙØªØ´ÙÙØ± Ø§ÙØØ¯ÙØ«: .
- - جدÙ٠بÙ
ÙØ§ØµÙات ÙÙ
ØØ±Ùات اÙÙØºØ© ÙÙØ§Ø¨ÙÙØ© دعÙ
ÙÙ Ù
ØØ±Ù ÙÙÙ Ø®Ø§ØµÙØ©.
+=======
+- - per-feature tables of support, e.g. to see which engines support modern cryptography functions: .
+- - a table with language features and engines that support those or don't support.
+
+All these resources are useful in real-life development, as they contain valuable information about language details, their support, etc.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ ÙØ°Ù اÙÙ
صادر Ù
ÙÙØ¯Ø© Ù٠تطÙÙØ± Ø§ÙØÙØ§Ø© اÙÙØ§ÙØ¹ÙØ©Ø ÙØ£ÙÙØ§ ØªØØªÙ٠عÙÙ Ù
عÙÙÙ
ات ÙÙÙÙ
Ø© Ø¹Ù ØªÙØ§ØµÙÙ ÙØ¯Ø¹Ù
اÙÙØºØ©.
diff --git a/1-js/01-getting-started/3-code-editors/article.md b/1-js/01-getting-started/3-code-editors/article.md
index 43b7fdba8..9c46f3b13 100644
--- a/1-js/01-getting-started/3-code-editors/article.md
+++ b/1-js/01-getting-started/3-code-editors/article.md
@@ -12,8 +12,13 @@
إذا ÙÙ
تÙÙ
Ø¨Ø§Ø®ØªÙØ§Ø± IDE Ø¨Ø¹Ø¯Ø ÙÙÙØ± ÙÙ Ø§ÙØ®Ùارات Ø§ÙØªØ§ÙÙØ©:
+<<<<<<< HEAD
- [ÙÙØ¬Ùا٠ستدÙÙ ÙÙØ¯](https://code.visualstudio.com/) (ÙØ¹Ù
٠عÙÙ Ø£ÙØ«Ø± Ù
Ù ÙØ¸Ø§Ù
تشغÙÙØ Ù
جاÙÙ).
- [ÙÙØ¨ Ø³ØªÙØ±Ù
](http://www.jetbrains.com/webstorm/) (ÙØ¹Ù
٠عÙÙ Ø£ÙØ«Ø± Ù
Ù ÙØ¸Ø§Ù
تشغÙÙØ Ù
دÙÙØ¹).
+=======
+- [Visual Studio Code](https://code.visualstudio.com/) (cross-platform, free).
+- [WebStorm](https://www.jetbrains.com/webstorm/) (cross-platform, paid).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
باÙÙØ³Ø¨Ø© ÙÙÙÙÙØ¯ÙØ²Ø ÙÙ
Ù٠استخداÙ
Ø¨Ø±ÙØ§Ù
ج ÙÙØ¬Ùا٠ستدÙÙØ ÙØ§Ùجب Ø§ÙØ®ÙØ· بÙÙÙ ÙØ¨Ù٠اÙÙÙØ¬Ùا٠ستدÙÙ ÙÙØ¯Ø ÙÙØ¬Ùا٠ستدÙÙ ÙÙ Ù
ØØ±Ø± Ù
دÙÙØ¹ ÙØ¹Ù
٠عÙÙ ÙØ¸Ø§Ù
ÙÙÙØ¯Ùز ÙÙØ·Ø ÙÙ
ÙØ§Ø³Ø¨ تÙ
اÙ
Ø§Ù ÙØ¨Ùئة اÙÙ.NET. Ø£ÙÙ Ø£ÙØ¶Ø§Ù Ø¬ÙØ¯ ÙØ¬Ø§Ùا Ø³ÙØ±Ùبت. ÙÙ
ا ÙÙØ¬Ø¯ إصدار Ù
جاÙÙ Ù
ÙÙ [Visual Studio Community](https://www.visualstudio.com/vs/community/).
@@ -29,6 +34,7 @@
Ø§ÙØ®Ùارات Ø§ÙØªØ§ÙÙØ© تستØÙ Ø§ÙØªØ¨Ø§ÙÙ:
+<<<<<<< HEAD
- [Atom](https://atom.io/) (ÙØ¹Ù
٠عÙÙ Ø§ÙØ¹Ø¯Ùد Ù
Ù Ø£ÙØ¸Ù
Ø© Ø§ÙØªØ´ØºÙÙØ Ù
جاÙÙ).
- [Visual Studio Code](https://code.visualstudio.com/) (ÙØ¹Ù
٠عÙÙ Ø§ÙØ¹Ø¯Ùد Ù
Ù Ø£ÙØ¸Ù
Ø© Ø§ÙØªØ´ØºÙÙØ Ù
جاÙÙ).
- [Sublime Text](http://www.sublimetext.com) (ÙØ¹Ù
٠عÙÙ Ø§ÙØ¹Ø¯Ùد Ù
Ù Ø£ÙØ¸Ù
Ø© Ø§ÙØªØ´ØºÙÙØ Ø¨Ø±ÙØ§Ù
ج Ù
Ø´Ø§Ø±ÙØ©).
@@ -36,9 +42,27 @@
- [Vim](http://www.vim.org/) Ù [Emacs](https://www.gnu.org/software/emacs/) رائعة إذا ÙÙØª تعر٠ÙÙÙÙØ© استخداÙ
ÙØ§.
## دعÙÙØ§ ÙØ§ ÙØªØ´Ø§Ø¬Ø±
+=======
+There are many options, for instance:
+
+- [Sublime Text](https://www.sublimetext.com/) (cross-platform, shareware).
+- [Notepad++](https://notepad-plus-plus.org/) (Windows, free).
+- [Vim](https://www.vim.org/) and [Emacs](https://www.gnu.org/software/emacs/) are also cool if you know how to use them.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
اÙÙ
ØØ±Ø±Ø§Øª Ø£Ø¹ÙØ§Ù ÙÙ Ø§ÙØªÙ ÙÙÙÙ
باستخداÙ
ÙØ§ Ø£ÙØ§ ÙØ£ØµØ¯ÙØ§Ø¦ÙØ ÙØ§ÙذÙÙ Ø£Ø¹ØªÙØ¯ Ø£ÙÙÙ
Ù
Ø·ÙØ±ÙÙ Ø¬ÙØ¯ÙÙ ÙØ³ØªØ®Ø¯Ù
ÙÙÙØ§ Ù
ÙØ° ÙÙØª Ø·ÙÙÙ ÙØªØ³Ø¹Ø¯ÙÙ
.
ÙÙØ¬Ø¯ Ø£ÙØ¶Ø§Ù Ù
ØØ±Ø±Ø§Øª رائعة Ù٠عاÙÙ
ÙØ§ اÙÙØ¨ÙØ±Ø Ø§ÙØ±Ø¬Ø§Ø¡ Ø§Ø®ØªÙØ§Ø± اÙÙ
ØØ±Ø± Ø§ÙØ°Ù ØªÙØ¶ÙÙ.
+<<<<<<< HEAD
Ø§Ø®ØªÙØ§Ø± اÙÙ
ØØ±Ø±Ø Ù
ث٠أ٠أداة Ø£Ø®Ø±ÙØ ÙÙ Ø§Ø®ØªÙØ§Ø± ÙØ±Ø¯Ù ÙÙØ¹ØªÙ
د عÙÙ Ù
Ø´Ø±ÙØ¹Ø§ØªÙØ ÙØ¹Ø§Ø¯Ø§ØªÙØ ÙØªÙضÙÙØ§ØªÙ Ø§ÙØ´Ø®ØµÙØ©.
+=======
+There are other great editors in our big world. Please choose the one you like the most.
+
+The choice of an editor, like any other tool, is individual and depends on your projects, habits, and personal preferences.
+
+The author's personal opinion:
+
+- I'd use [Visual Studio Code](https://code.visualstudio.com/) if I develop mostly frontend.
+- Otherwise, if it's mostly another language/platform and partially frontend, then consider other editors, such as XCode (Mac), Visual Studio (Windows) or Jetbrains family (Webstorm, PHPStorm, RubyMine etc, depending on the language).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/01-getting-started/4-devtools/article.md b/1-js/01-getting-started/4-devtools/article.md
index 3dded1566..a86c622ae 100644
--- a/1-js/01-getting-started/4-devtools/article.md
+++ b/1-js/01-getting-started/4-devtools/article.md
@@ -8,7 +8,11 @@
ÙÙØ¶Ù Ù
عظÙ
اÙÙ
Ø·ÙØ±ÙÙ Ø§ÙØ¹Ù
٠عÙÙ Ù
تصÙÙÙØÙ Chrome Ø£Ù FireFox ÙØ§ØØªÙائÙÙ
ا عÙÙ Ø£ÙØ¶Ù Ø£Ø¯ÙØ§Øª اÙÙ
Ø·ÙÙØ±. تÙÙØ± اÙÙ
تصÙÙÙØØ§Øª Ø§ÙØ£Ø®Ø±Ù Ø£ÙØ¶Ùا Ù
جÙ
ÙØ¹Ø© Ø£Ø¯ÙØ§Øª ÙÙÙ
Ø·ÙÙØ± ÙØ§Ùت٠Ù
٠اÙÙ
Ù
ÙÙ Ø£Ù ØªØØªÙ٠عÙÙ Ù
Ø²Ø§ÙØ§ خاصة. ÙÙ٠عادة٠Ù
ا ØªØØ§Ù٠اÙÙØØ§Ù Ø¨Ù
تصÙÙÙØÙ Chrome Ù FireFox Ø§ÙØ£Ùض٠Ù
Ù ÙØ°Ù اÙÙØ§ØÙØ©. ÙÙØ¶Ù اÙÙ
Ø·ÙÙØ±Ù٠بشÙ٠عاÙ
Ø§ÙØ¹Ù
٠عÙÙ Ù
تصÙÙÙØ ÙØ§ØØ¯ ÙÙÙØªÙÙÙ٠إÙÙ Ù
تصÙÙÙØ آخر Ø¹ÙØ¯Ù
ا تÙÙ٠اÙÙ
Ø´ÙÙØ© Ø§ÙØªÙ ÙØ¹Ù
ÙÙ٠عÙÙÙØ§ Ù
ØØ¯ÙÙØ¯Ø© Ø¨ÙØ°Ø§ اÙÙ
تصÙÙÙØ.
+<<<<<<< HEAD
Ø¨ÙØ§Ø¡Ù عÙ٠ذÙÙØ ÙØ¬Ø¯ Ø£ÙÙÙ Ø£Ø¯ÙØ§Øª اÙÙ
Ø·ÙØ± Ù
ÙÙ
Ø© ÙÙØºØ§ÙØ© ÙÙ
ا تÙ
تÙÙÙ Ù
Ù Ù
Ø²Ø§ÙØ§ ØªØ³Ø§Ø¹Ø¯Ù Ø£Ø«ÙØ§Ø¡ Ù
Ø³ÙØ±ØªÙ Ù٠تطÙÙØ± اÙÙÙØ¨ عبر JavaScript. Ø³ÙØªØ¹ÙÙ
ÙÙ Ø§ÙØ¨Ø¯Ø§ÙØ© طرÙÙØ© ÙØªØÙØ§Ø ÙØ§Ø³ØªØ®Ø¯Ø§Ù
ÙØ§ ÙØ§Ø³ØªÙØ´Ø§Ù Ø§ÙØ£Ø®Ø·Ø§Ø¡Ø ÙØªØ´ØºÙ٠تعÙÙÙ
ات JavaScript ضÙ
ÙÙØ§.
+=======
+Developer tools are potent; they have many features. To start, we'll learn how to open them, look at errors, and run JavaScript commands.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø£Ø¯ÙØ§Øª اÙÙ
Ø·ÙØ± ÙÙÙØ©, ÙØ¯ÙÙØ§ Ø§ÙØ¹Ø¯Ùد Ù
٠اÙÙ
ÙØ²Ø§Øª. ÙÙØ¨Ø¯Ø¡, Ø³ÙØªØ¹ÙÙ
ÙÙÙÙØ© ÙØªØÙا Ø ÙØ§ÙÙØ¸Ø± ÙÙ Ø§ÙØ£Ø®Ø·Ø§Ø¡ Ø ÙØªØ´ØºÙÙ Ø£ÙØ§Ù
ر Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت.
@@ -25,8 +29,12 @@
Ø§ÙØ¢Ù Ø£ØµØ¨Ø Ø¨Ø¥Ù
ÙØ§ÙÙ Ø§Ø³ØªÙØ´Ø§Ù Ø§ÙØ£Ø®Ø·Ø§Ø¡Ø ÙÙØ°Ø§ ÙÙÙÙ Ø¨Ø¯Ø§ÙØ© ÙØ³ÙØ¹ÙØ¯ ÙØ§ØÙÙØ§ Ø¥ÙÙ Ø£Ø¯ÙØ§Øª اÙÙ
Ø·ÙÙØ± ÙÙØ¯Ø±Ø³ Ø§Ø³ØªÙØ´Ø§Ù Ø§ÙØ£Ø®Ø·Ø§Ø¡ ÙØ¥ØµÙاØÙا Ø£Ù Ù
ا ÙØ¹Ø±Ù debugging ÙÙ ÙØµÙ تÙÙÙØ Ø§ÙØ£Ø®Ø·Ø§Ø¡ Ù٠اÙÙ
تصÙÙÙØ Chrome.
+<<<<<<< HEAD
## Ø£Ø¯ÙØ§Øª اÙÙ
Ø·ÙØ± ÙÙ Ù
ØªØµÙØÙ FireFox Ù Safari ÙØºÙرÙÙ
ا
ØªÙØ³ØªØ®Ø¯ÙÙ
Ù
عظÙ
اÙÙ
تصÙÙÙØØ§Øª Ø§ÙØ§Ø®ØªØµØ§Ø± F12 ÙÙØªØ Ø£Ø¯ÙØ§Øª اÙÙ
Ø·ÙÙØ±. بشÙ٠عاÙ
ØªØªØ´Ø§Ø¨Ù ÙØ°Ù Ø§ÙØ£Ø¯Ùات ÙÙ Ø§ÙØ´ÙÙ ÙØ§ÙÙ
ضÙ
ÙÙ. ÙØ¨Ù
جرد تعÙÙ
Ù Ø§ÙØ¹Ù
٠عÙÙ Ø¥ØØ¯Ù ÙØ°Ù Ø§ÙØ£Ø¯Ùات (بإÙ
ÙØ§ÙÙ Ø§ÙØ¨Ø¯Ø¡ Ù
ع Chrome)Ø ÙÙ
ÙÙ٠بسÙÙÙØ© Ø§ÙØ§ÙØªÙØ§Ù ÙÙØ¹Ù
٠عÙÙ Ø§ÙØ£Ø¯Ùات Ø§ÙØ£Ø®Ø±Ù.
+=======
+
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
### Ø£Ø¯ÙØ§Øª اÙÙ
Ø·ÙØ± ÙÙ Ù
ØªØµÙØ Safari
ÙØ®ØªÙ٠اÙÙ
تصÙÙÙØ Safari (Ù
تصÙÙÙØ خاص Ø¨ÙØ¸Ø§Ù
Ø§ÙØªØ´ØºÙ٠«Ù
اÙ» ÙØºÙر Ù
دعÙÙ
Ù
Ù ÙØ¨Ù «ÙÙÙØ¯Ùز» أ٠«ÙÙÙÙØ³Â») Ù٠طرÙÙØ© ÙØªØ Ø£Ø¯ÙØ§Øª اÙÙ
Ø·ÙØ±. ÙØØªØ§Ø¬ ÙÙ Ø§ÙØ¨Ø¯Ø§ÙØ© ÙØªÙعÙÙ Â«ÙØ§Ø¦Ù
Ø© اÙÙ
Ø·ÙÙØ±Â» (Develop menu). ÙÙØ¹Ù ذÙÙØ Ø§ÙØªØ Â«Ø§ÙØªÙضÙÙØ§ØªÂ» (Preferences) Ø«Ù
اختر ÙØ§Ø¦Ù
Ø© «Ù
ØªÙØ¯Ù
» (Advanced). ÙÙØ¬Ø¯ ÙÙ Ø§ÙØ£Ø³ÙÙ Ù
ربع Ø§Ø®ØªÙØ§Ø± ÙØ¥Ø¸Ùار ÙØ§Ø¦Ù
Ø© اÙÙ
Ø·ÙÙØ± ÙÙ Ø´Ø±ÙØ· اÙÙØ§Ø¦Ù
Ø©. ØØ¯Ø¯Ù ÙØªÙعÙ٠اÙÙØ§Ø¦Ù
Ø©:
@@ -44,3 +52,28 @@
ترجÙ
Ø© -ÙØ¨ØªØµØ±Ù- ÙÙÙØµÙ [Developer Console](https://javascript.info/devtools) Ù
Ù ÙØªØ§Ø¨ [The JavaScript Language](https://javascript.info/js)
+<<<<<<< HEAD
+=======
+## Firefox, Edge, and others
+
+Most other browsers use `key:F12` to open developer tools.
+
+The look & feel of them is quite similar. Once you know how to use one of these tools (you can start with Chrome), you can easily switch to another.
+
+## Safari
+
+Safari (Mac browser, not supported by Windows/Linux) is a little bit special here. We need to enable the "Develop menu" first.
+
+Open Settings and go to the "Advanced" pane. There's a checkbox at the bottom:
+
+
+
+Now `key:Cmd+Opt+C` can toggle the console. Also, note that the new top menu item named "Develop" has appeared. It has many commands and options.
+
+## Summary
+
+- Developer tools allow us to see errors, run commands, examine variables, and much more.
+- They can be opened with `key:F12` for most browsers on Windows. Chrome for Mac needs `key:Cmd+Opt+J`, Safari: `key:Cmd+Opt+C` (need to enable first).
+
+Now we have the environment ready. In the next section, we'll get down to JavaScript.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/01-getting-started/4-devtools/chrome.png b/1-js/01-getting-started/4-devtools/chrome.png
deleted file mode 100644
index 4cb3ea2f4..000000000
Binary files a/1-js/01-getting-started/4-devtools/chrome.png and /dev/null differ
diff --git a/1-js/01-getting-started/4-devtools/chrome.webp b/1-js/01-getting-started/4-devtools/chrome.webp
new file mode 100644
index 000000000..bdf067079
Binary files /dev/null and b/1-js/01-getting-started/4-devtools/chrome.webp differ
diff --git a/1-js/01-getting-started/4-devtools/[email protected] b/1-js/01-getting-started/4-devtools/[email protected]
new file mode 100644
index 000000000..2aeca5898
Binary files /dev/null and b/1-js/01-getting-started/4-devtools/[email protected] differ
diff --git a/1-js/01-getting-started/4-devtools/[email protected] b/1-js/01-getting-started/4-devtools/[email protected]
deleted file mode 100644
index b87404a8f..000000000
Binary files a/1-js/01-getting-started/4-devtools/[email protected] and /dev/null differ
diff --git a/1-js/01-getting-started/4-devtools/safari.png b/1-js/01-getting-started/4-devtools/safari.png
index 64c7a3f6c..4538827eb 100644
Binary files a/1-js/01-getting-started/4-devtools/safari.png and b/1-js/01-getting-started/4-devtools/safari.png differ
diff --git a/1-js/01-getting-started/4-devtools/[email protected] b/1-js/01-getting-started/4-devtools/[email protected]
index 27def4d09..1561b2bd9 100644
Binary files a/1-js/01-getting-started/4-devtools/[email protected] and b/1-js/01-getting-started/4-devtools/[email protected] differ
diff --git a/1-js/02-first-steps/01-hello-world/article.md b/1-js/02-first-steps/01-hello-world/article.md
index c414004ce..ab93f74b1 100644
--- a/1-js/02-first-steps/01-hello-world/article.md
+++ b/1-js/02-first-steps/01-hello-world/article.md
@@ -73,7 +73,11 @@
```
+<<<<<<< HEAD
ÙÙØ§Ø `/path/to/script.js` ÙÙ Ù
سار Ù
ÙÙØ±Ø¯ ÙÙÙØµ Ø§ÙØ¨Ø±Ù
ج٠Ù
٠جذر اÙÙ
ÙÙØ¹. ÙÙ
ÙÙ Ø£ÙØ¶Ø§Ù تÙÙÙØ± Ù
سار ÙØ³Ø¨Ù Ù
Ù Ø®ÙØ§Ù Ø§ÙØµÙØØ© Ø§ÙØØ§ÙÙØ©. عÙ٠سبÙ٠اÙÙ
Ø«Ø§ÙØ `src="script.js"` تعÙ٠أ٠اÙÙ
ÙÙ `"script.js"` ÙÙ ÙÙØ³ اÙÙ
Ø¬ÙØ¯.
+=======
+Here, `/path/to/script.js` is an absolute path to the script from the site root. One can also provide a relative path from the current page. For instance, `src="script.js"`, just like `src="./script.js"`, would mean a file `"script.js"` in the current folder.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
ÙÙ Ø£Ù ÙØ¹Ø·Ù اÙÙ
سار اÙÙØ§Ù
Ù Ø£ÙØ¶Ø§Ù. عÙ٠سبÙ٠اÙÙ
ثا٠:
diff --git a/1-js/02-first-steps/02-structure/article.md b/1-js/02-first-steps/02-structure/article.md
index 6285c198d..138f6a365 100644
--- a/1-js/02-first-steps/02-structure/article.md
+++ b/1-js/02-first-steps/02-structure/article.md
@@ -46,6 +46,7 @@ alert(3+
ÙØ±ÙØ¨ÙØ§ Ø®ÙØ§Ù Ø§ÙØ´ÙÙØ±Ø§Øª Ø§ÙØªÙ Ø³ØªÙØªØ¨Ùا).
إذا ÙÙØª ترغب ÙÙ Ø§ÙØ§Ø·Ùاع عÙÙ Ù
Ø«Ø§Ù ÙØ§ÙØ¹Ù Ø¹Ù ÙØ°Ù Ø§ÙØØ§ÙØ©Ø Ø¥ÙÙÙ Ø§ÙØ´ÙÙØ±Ø© Ø§ÙØ¨Ø±Ù
Ø¬ÙØ© Ø§ÙØªØ§ÙÙØ©:
+<<<<<<< HEAD
```
[1, 2].foreach(alert)
```
@@ -55,10 +56,36 @@ alert(3+
```
alert("There will be an error")
[1 ,2].forEach(alert)
+=======
+The code outputs `6` because JavaScript does not insert semicolons here. It is intuitively obvious that if the line ends with a plus `"+"`, then it is an "incomplete expression", so a semicolon there would be incorrect. And in this case, that works as intended.
+
+**But there are situations where JavaScript "fails" to assume a semicolon where it is really needed.**
+
+Errors which occur in such cases are quite hard to find and fix.
+
+````smart header="An example of an error"
+If you're curious to see a concrete example of such an error, check this code out:
+
+```js run
+alert("Hello");
+
+[1, 2].forEach(alert);
+```
+
+No need to think about the meaning of the brackets `[]` and `forEach` yet. We'll study them later. For now, just remember the result of running the code: it shows `Hello`, then `1`, then `2`.
+
+Now let's remove the semicolon after the `alert`:
+
+```js run no-beautify
+alert("Hello")
+
+[1, 2].forEach(alert);
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
Ø¹ÙØ¯ تÙÙÙØ° Ø§ÙØ´ÙÙØ±Ø© Ø§ÙØ¨Ø±Ù
Ø¬ÙØ© Ø¢ÙØ°Ø§ÙØ Ø³ÙØªÙ
Ø¥Ø¸ÙØ§Ø± Ø§ÙØªÙبÙÙ Ø§ÙØ£ÙÙ ÙÙØ· Ø«Ù
Ø³ÙØØµÙ Ø¹Ù٠خطأ. ØªØ¹ÙØ¯ Ø§ÙØ´ÙÙØ±Ø© Ø§ÙØ¨Ø±Ù
Ø¬ÙØ© ÙÙØ¹Ù
٠بشÙÙ
صØÙØ Ù
رة Ø£Ø®Ø±Ù Ø¹ÙØ¯ Ø¥Ø¶Ø§ÙØ© اÙÙØ§ØµÙØ© اÙÙ
ÙÙÙØ·Ø© بعد Ø§ÙØªÙبÙÙ Ø§ÙØ£ÙÙ:
+<<<<<<< HEAD
```
alert("All fine now");
[1 ,2].forEach(alert)
@@ -72,6 +99,18 @@ alert("All fine now");
```
alert("There will be an error")[1, 2].forEach(alert)
+=======
+The difference compared to the code above is only one character: the semicolon at the end of the first line is gone.
+
+If we run this code, only the first `Hello` shows (and there's an error, you may need to open the console to see it). There are no numbers any more.
+
+That's because JavaScript does not assume a semicolon before square brackets `[...]`. So, the code in the last example is treated as a single statement.
+
+Here's how the engine sees it:
+
+```js run no-beautify
+alert("Hello")[1, 2].forEach(alert);
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
ÙÙÙÙÙÙ
ا عبارتÙ٠برÙ
Ø¬ÙØªÙÙ Ù
ÙÙØµÙتÙÙ ÙÙÙØ³ØªØ§ عبارة ÙØ§ØØ¯Ø©Ø ÙØ¨Ø§ÙتاÙ٠عÙ
ÙÙØ© Ø§ÙØ¯Ù
ج ÙÙ ÙØ°Ù Ø§ÙØØ§ÙØ© خطأ. Ù
٠اÙÙ
Ù
ÙÙ Ø£Ù ØªØªÙØ±Ø±
ÙØ°Ù Ø§ÙØØ§ÙØ© ضÙ
Ù Ø´Ø±ÙØ· أخرÙ.
@@ -80,12 +119,19 @@ alert("There will be an error")[1, 2].forEach(alert)
ÙÙ Ù
عظÙ
Ø§ÙØØ§ÙØ§ØªØ ÙÙÙÙ Ù
Ù Ø§ÙØ£ÙØ¶Ù Ø¥Ø¶Ø§ÙØªÙا Ù٠آخر Ø§ÙØ¹Ø¨Ø§Ø±Ø© Ø§ÙØ¨Ø±Ù
Ø¬ÙØ© - ÙØ®Ø§ØµØ©Ù باÙÙØ³Ø¨Ø© ÙÙÙ
بتدئÙÙ - ØªØ¬ÙØ¨Ùا ÙÙÙÙÙØ¹ Ù٠أخطاء
Ø¹ØµÙØ© Ø§ÙØªÙÙÙØ ÙØ§ÙتصØÙØ Ø£ÙØª بغÙÙ٠عÙÙØ§.
+<<<<<<< HEAD
## Ø§ÙØªØ¹ÙÙÙØ§Øª
ØªØµØ¨Ø Ø§ÙØ¨Ø±Ø§Ù
ج Ø£ÙØ«Ø± تعÙÙØ¯Ùا Ù
ع Ù
Ø±ÙØ± اÙÙÙØª. ÙÙÙÙÙ Ø¶Ø±ÙØ±ÙÙØ§ Ø¥Ø¶Ø§ÙØ© Ø§ÙØªØ¹ÙÙÙØ§Øª ÙØ´Ø±Ø عÙ
Ù Ø§ÙØ´ÙÙØ±Ø© Ø§ÙØ¨Ø±Ù
Ø¬ÙØ©. ÙÙ
ÙÙ ÙØ¶Ø¹
Ø§ÙØªØ¹ÙÙÙØ§Øª Ù٠أ٠Ù
ÙØ§Ù ضÙ
Ù Ø§ÙØ³Ùربت دÙ٠أ٠تؤثر عÙ٠تÙÙÙØ°ÙØ ÙØ£ÙÙ٠اÙÙ
ØØ±Ù ببساطة ÙØªØ¬Ø§Ù٠جÙ
ÙØ¹ Ø§ÙØªØ¹ÙÙÙØ§Øª.
**Ø§ÙØªØ¹ÙÙÙØ§Øª اÙÙ
ÙØªÙبة عÙ٠سطر ÙØ§ØØ¯ تبدأ بخطÙÙ Ù
ائÙÙÙ (forward slash) Ø¨Ø§ÙØ´ÙÙ `//`**. ÙÙÙÙÙ Ø§ÙØ¬Ø²Ø¡ Ø§ÙØªØ§ÙÙ ÙÙØ®Ø·ÙÙ
اÙÙ
ائÙÙ٠عÙÙ ÙÙØ³ Ø§ÙØ³Ø·Ø± تعÙÙÙÙØ§. ÙÙ
٠اÙÙ
Ù
ÙÙ Ø£Ù ÙØ´ØºÙ Ø§ÙØªØ¹ÙÙÙ Ø³Ø·Ø±ÙØ§ ÙØ§Ù
ÙÙØ§ Ø£Ù ÙØ£ØªÙ Ø§ÙØªØ¹ÙÙ٠بعد Ø§ÙØ¹Ø¨Ø§Ø±Ø© Ø§ÙØ¨Ø±Ù
Ø¬ÙØ©.
Ø¥ÙÙ٠اÙÙ
Ø«Ø§Ù Ø§ÙØªØ§ÙÙ Ø§ÙØ°Ù ÙØ´Ø±Ø Ù
ا سبÙ:
+=======
+Looks weird, right? Such merging in this case is just wrong. We need to put a semicolon after `alert` for the code to work correctly.
+
+This can happen in other situations also.
+````
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
diff --git a/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md b/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md
index 401369861..34666a10c 100644
--- a/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md
+++ b/1-js/02-first-steps/04-variables/3-uppercast-constant/task.md
@@ -12,13 +12,24 @@ const birthday = '18.04.1982';
const age = someCode(birthday);
```
+<<<<<<< HEAD
ÙÙØ§ ÙØÙ ÙÙ
تÙ٠ثابت ÙØØ²Ù ÙÙÙ
Ø© Ø§ÙØªØ§Ø±ÙØ® `birthday` ٠ثابت أخر ÙØ³Ù
Ù `age` ÙØØ³Ø¨ ÙÙÙ
Ø© Ø§ÙØ¹Ù
ر Ù
Ù Ø§ÙØ«Ø§Ø¨Øª `birthday` Ù
ع Ù
ساعدة Ø§ÙØ¯Ø§Ù٠بعض اÙÙÙØ¯ (ÙÙ
ÙØªÙ
تÙÙÙØ±Ùا ÙØªØµØºÙØ±ÙØ§ Ø ÙÙØ£Ù Ø§ÙØªÙاصÙÙ ÙØ§ تÙÙ
ÙÙØ§)
+=======
+Here we have a constant `birthday` for the date, and also the `age` constant.
+
+The `age` is calculated from `birthday` using `someCode()`, which means a function call that we didn't explain yet (we will soon!), but the details don't matter here, the point is that `age` is calculated somehow based on the `birthday`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ Ù
Ù Ø§ÙØµØÙØ Ø£Ø³ØªØ®Ø¯Ø§Ù
Ø§ÙØØ±Ù٠اÙÙØ¨Ùر٠ÙÙØ«Ø§Ø¨Øª `birthday` Ø Ø§Ù ÙÙØ«Ø§Ø¨Øª `age`Ø Ø§Ù ØØªÙ ÙÙÙÙÙÙ
اØ
```js
+<<<<<<< HEAD
const BIRTHDAY = '18.04.1982'; // ÙÙ ÙØ¬Ø¹Ù Ø§ÙØ§Ø³Ù
ذات ØØ±ÙÙ ÙØ¨ÙØ±ÙØ
const AGE = someCode(BIRTHDAY); // ÙÙ ÙØ¬Ø¹Ù Ø§ÙØ§Ø³Ù
ذات ØØ±ÙÙ ÙØ¨ÙØ±ÙØ
-```
+=======
+const BIRTHDAY = '18.04.1982'; // make birthday uppercase?
+const AGE = someCode(BIRTHDAY); // make age uppercase?
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
+```
diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md
index 89d21f287..203cec973 100644
--- a/1-js/02-first-steps/04-variables/article.md
+++ b/1-js/02-first-steps/04-variables/article.md
@@ -26,7 +26,11 @@ let message;
let message;
*!*
+<<<<<<< HEAD
message = 'Hello'; // تخزÙ٠اÙÙØµ
+=======
+message = 'Hello'; // store the string 'Hello' in the variable named message
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
*/!*
```
@@ -66,7 +70,12 @@ let age = 25;
let message = 'Hello';
```
+<<<<<<< HEAD
بعض اÙÙØ§Ø³ Ø§ÙØ¶Ø§ ÙÙØ¹Ø±ÙÙ٠اÙÙ
ØªØºÙØ±Ø§Øª Ø¨ÙØ°Ù Ø§ÙØ·Ø±ÙÙÙ:
+=======
+Some people also define multiple variables in this multiline style:
+
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js no-beautify
let user = 'John',
age = 25,
@@ -90,20 +99,37 @@ let user = 'John'
*!*var*/!* message = 'Hello';
```
+<<<<<<< HEAD
اÙÙÙÙ
Ø© `var` تÙÙÙ *ØºØ§ÙØ¨Ø§* ÙÙØ³ اÙÙÙÙ
Ù `let`. ÙÙÙ Ø§ÙØ¶Ø§ تعÙ٠ع٠Ù
ØªØºÙØ±, ÙÙÙÙ ÙÙ Ù
Ø¸ÙØ± Ù
ختÙÙ, طرÙÙØ© "Ù
Ø¯Ø±Ø³Ù ÙØ¯ÙÙ
Ù".
ÙÙØ§Ù Ø§Ø®ØªÙØ§Ùات دÙÙÙ٠بÙÙ `let` Ù `var` , ÙÙÙÙ ÙØ§ تÙÙÙ
ÙØ§ بعد. ÙØÙ Ø³ÙÙ ÙØºØ·Ù ÙØ°Ù Ø§ÙØ§Ø®ØªÙØ§ÙØ§Øª Ø¨ØªÙØµÙÙ Ù٠اÙÙØµÙ .
+=======
+The `var` keyword is *almost* the same as `let`. It also declares a variable but in a slightly different, "old-school" way.
+
+There are subtle differences between `let` and `var`, but they do not matter to us yet. We'll cover them in detail in the chapter .
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
````
## Ø§ÙØªØ¬Ø§Ùس Ø§ÙØÙÙÙÙ
+<<<<<<< HEAD
ÙØÙ ÙØ³ØªØ·Ùع بسÙÙÙÙ Ø£Ø³ØªÙØ¹Ø§Ø¨ Ù
ÙÙÙÙ
اÙÙ
ØªØºÙØ± Ù٠تخÙÙÙØ§ اÙÙ Ø¹Ø¨Ø§Ø±Ù Ø¹Ù ØµÙØ¯ÙÙ ÙØªØ®Ø²ÙÙ Ø§ÙØ¨ÙØ§ÙØ§Øª, Ù
ÙØµÙ٠عÙÙ٠اسÙ
Ù
خصص ÙÙ ÙÙØ· ÙÙØØªÙ٠بداخÙ٠عÙÙ ÙÙÙ
٠اÙÙØ§ بداخÙÙ.
+=======
+We can easily grasp the concept of a "variable" if we imagine it as a "box" for data, with a uniquely-named sticker on it.
+
+For instance, the variable `message` can be imagined as a box labelled `"message"` with the value `"Hello!"` in it:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11

ÙØ³ØªØ·Ùع Ø£Ù ÙØ¶Ø¹ Ø£Ù ÙÙÙ
Ø© Ø¨Ø¯Ø§Ø®Ù Ø§ÙØµÙدÙÙ.
+<<<<<<< HEAD
ÙÙØ³ØªØ·Ùع Ø£ÙØ¶Ø§ تغÙÙØ± ÙÙÙ
ØªÙ Ø£ÙØ«Ø± Ù
Ù Ù
ر٠ÙÙ
ا ÙØ±Ùد.
+=======
+We can also change it as many times as we want:
+
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let message;
@@ -150,11 +176,19 @@ So, we should declare a variable once and then refer to it without `let`.
````
```smart header="Functional languages"
+<<<<<<< HEAD
Ù
٠اÙÙ
Ø«ÙØ± ÙÙØ§ÙتÙ
اÙ
Ù
ÙØ§ØØ¸Ø© ÙØ¬Ùد [ÙØ¸ÙÙÙ](https://en.wikipedia.org/wiki/Functional_programming) ÙØºØ§Øª برÙ
جÙ, Ù
ث٠[Scala](http://www.scala-lang.org/) ا٠[Erlang](http://www.erlang.org/) تÙ
ÙØ¹ تغÙÙØ± ÙÙÙ
اÙÙ
ØªØºÙØ±.
+=======
+It's interesting to note that there exist so-called [pure functional](https://en.wikipedia.org/wiki/Purely_functional_programming) programming languages, such as [Haskell](https://en.wikipedia.org/wiki/Haskell), that forbid changing variable values.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ ÙØ°Ù اÙÙØºØ§Øª, اÙÙÙÙ
Ù Ø§ÙØ§ÙÙÙ ØªÙØ®Ø²Ù ÙÙ Ø§ÙØµÙدÙÙ, ÙØªÙÙÙ ÙÙØ§Ø¨Ø¯. ٠اذا Ø£Ø±Ø¯ÙØ§ تخزÙÙ ÙÙÙ
Ù ØºÙØ±Ùا, اÙÙØºÙ تÙÙØ´Ø¦ ÙÙØ§ ØµÙØ¯ÙÙ Ø¬Ø¯ÙØ¯ (تعرÙÙ Ù
ØªØºÙØ± Ø¬Ø¯ÙØ¯). ÙÙØ§ ÙØ³ØªØ·Ùع أعاد٠استخداÙ
اÙÙ
ØªØºÙØ± اÙÙØ¯ÙÙ
.
+<<<<<<< HEAD
عÙÙ Ø§ÙØ±ØºÙ
Ù
٠أÙÙ ÙØ¯ ÙØ¨Ø¯Ùا ØºØ±ÙØ¨Ø§ ÙÙÙÙÙØ© Ø§ÙØ§ÙÙÙ, ÙØ°Ù اÙÙØºØ§Øª ÙØ§Ø¯Ø±Ø© عÙÙ Ø§ÙØªØ·Ùر Ø§ÙØ¬Ø§Ø¯. Ø£ÙØ«Ø± Ù
٠ذÙÙ, ÙÙØ§Ù Ù
Ø¬Ø§ÙØ§Øª Ù
Ø«Ù Ø§ÙØØ³Ø§Ø¨Ø§Øª اÙÙ
ØªÙØ§Ø²ÙØ© ØÙØ« ÙÙ
ÙØ ÙØ°Ø§ اÙÙÙØ¯ ÙÙØ§Ø¦Ø¯ Ù
عÙÙØ©. ÙÙÙØµÙ بدراسة Ù
Ø«Ù ÙØ°Ù اÙÙØºØ© ÙØªÙØ³ÙØ¹ Ø§ÙØ¹ÙÙ.
+=======
+Though it may seem a little odd at first sight, these languages are quite capable of serious development. More than that, there are areas like parallel computations where this limitation confers certain benefits.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
## تسÙ
ÙØ© اÙÙ
ØªØºÙØ± [#variable-naming]
@@ -171,7 +205,11 @@ let userName;
let test123;
```
+<<<<<<< HEAD
Ø¹ÙØ¯Ù
ا ÙØØªÙÙ Ø§ÙØ§Ø³Ù
عÙÙ Ø£ÙØ«Ø± Ù
Ù ÙÙÙ
Ø©, [camelCase](https://en.wikipedia.org/wiki/CamelCase) تÙÙÙ Ø§ÙØ·Ø±ÙÙØ© Ø§ÙØ´Ø§Ø¦Ø¹Ù ÙÙØ§Ø³ØªØ®Ø¯Ø§Ù
. ÙÙÙÙÙ ÙØ°ÙÙ: اÙÙÙÙ
ات ØªÙØ±ØªØ¨ ÙØ§ØØ¯Ù تÙÙ Ø§ÙØ§Ø®Ø±Ù, ÙÙ ÙÙÙ
Ù Ù
ا عدا اÙÙÙÙ
Ù Ø§ÙØ§ÙÙ٠تبدأ Ø¨ØØ±Ù ÙØ¨Ùر:`myVeryLongName`.
+=======
+When the name contains multiple words, [camelCase](https://en.wikipedia.org/wiki/CamelCase) is commonly used. That is: words go one after another, with each word except the first starting with a capital letter: `myVeryLongName`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù
ا اÙÙ
Ø«ÙØ± ÙÙØ£ÙتÙ
اÙ
-- Ø¹ÙØ§Ù
Ø© Ø§ÙØ¯ÙÙØ§Ø± `'$'` ÙØ§ÙØªØ³Ø·ÙØ± `'_'` ÙØ³ØªØ·Ùع Ø£ÙØ¶Ø§ استخداÙ
ÙÙ
ÙÙ Ø§ÙØ§Ø³Ù
اء. Ø£ÙÙØ§ رÙ
ÙØ² عادÙÙ, ÙÙØ· Ù
Ø«Ù Ø§ÙØØ±ÙÙ,ÙØ¨Ø¯Ù٠أ٠Ù
عÙ٠أخر.
@@ -192,20 +230,33 @@ let 1a; // ÙØ§ ÙØ³ØªØ·Ùع ÙØ¨Ø¯Ø£ Ø§ÙØ§Ø³Ù
برÙÙ
let my-name; // اÙÙØ§ØµÙات '-' ØºÙØ± Ù
سÙ
ÙØ Ø¨ÙØ§ ÙÙ Ø§ÙØªØ³Ù
ÙØ©
```
+<<<<<<< HEAD
```smart header="اÙÙ
ÙØ§ØØ¸Ù اÙÙ
ÙÙ
Ù"
اÙÙ
ØªØºÙØ±Ø§Øª Ø§ÙØªÙ ØªÙØ³Ù
Ù `apple` Ù `AppLE` ÙÙÙÙÙØ§ Ù
ØªØºÙØ±ÙÙÙ Ù
ختÙÙÙ٠تÙ
اÙ
ا
```
````smart header="ÙÙØ³Ù
Ø Ø¨Ø§Ø³ØªØ®Ø¯Ø§Ù
Ø§ÙØ£ØØ±Ù ØºÙØ± اÙÙØ§ØªÙÙÙØ© Ø ÙÙÙÙ ÙØ§ ÙÙÙØµØ Ø¨ÙØ§"
Ù
٠اÙÙ
Ù
Ù٠أستخداÙ
Ø£Ù ÙØºØ©, بÙ
ا Ù٠ذÙÙ Ø§ÙØØ±ÙÙ Ø§ÙØ³ÙرÙÙÙØ© Ø£Ù ØØªÙ Ø§ÙØØ±Ù٠اÙÙÙØ±ÙغÙÙÙÙØ©, Ù
Ø«Ù ÙØ°Ù :
+=======
+```smart header="Case matters"
+Variables named `apple` and `APPLE` are two different variables.
+```
+
+````smart header="Non-Latin letters are allowed, but not recommended"
+It is possible to use any language, including Cyrillic letters, Chinese logograms and so on, like this:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
let Ð¸Ð¼Ñ = '...';
let æ = '...';
```
+<<<<<<< HEAD
تÙÙÙØ§Ù, ÙØ§ ÙÙØ¬Ø¯ خطأ ÙÙØ§, Ù
Ø«Ù ÙØ°Ù Ø§ÙØ§Ø³Ù
اء Ù
سÙ
ÙØ Ø¨ÙØ§, ÙÙÙÙ ÙÙØ§Ù ØªÙØ§ÙÙØ¯ عاÙÙ
ÙÙ ÙØ£Ø³ØªØ®Ø¯Ø§Ù
اÙÙØºÙ Ø§ÙØ§ÙجÙÙØ²ÙÙ Ù٠أسÙ
اء اÙÙ
ØªØºÙØ±Ø§Øª. ØØªÙ ÙÙ ÙÙØ§ ÙÙØªØ¨ ÙØµØ§Ù ØµØºÙØ±Ø§Ù, ÙØ¯ ÙÙÙÙ ÙÙØ§ ØÙاة Ø·ÙÙÙÙ Ù٠اÙÙ
Ø³ØªÙØ¨Ù. اÙÙØ§Ø³ Ù
Ù Ù
ختÙÙ Ø§ÙØ¨Ùاد ربÙ
ا ÙØØªØ§Ø¬ÙØ§ ÙÙØ±Ø£Ø¡ØªÙا ÙØ¨Ø¹Ø¶ اÙÙÙØª.
+=======
+Technically, there is no error here. Such names are allowed, but there is an international convention to use English in variable names. Even if we're writing a small script, it may have a long life ahead. People from other countries may need to read it sometime.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
````
````warn header="Ø§ÙØ£Ø³Ù
اء اÙÙ
ØØ¬ÙزÙ"
@@ -260,12 +311,20 @@ const myBirthday = '18.04.1982';
myBirthday = '01.01.2001'; // خطأ, ÙØ§ØªØ³ØªØ·Ùع تغÙÙØ± ÙÙÙ
Ø© Ø§ÙØ«Ø§Ø¨Øª
```
+<<<<<<< HEAD
Ø¹ÙØ¯Ù
ا اÙÙ
برÙ
ج ÙÙÙÙ Ù
ØªØ£ÙØ¯ أ٠اÙÙ
ØªØºÙØ± ÙÙ ÙØªØºÙر أبداÙ, ÙÙØ¬Ø¨ عÙÙ٠تعرÙ٠اÙÙ
ØªØºÙØ± بأستخداÙ
`const` ÙØ¶Ù
Ø§Ù ÙØ°Ù Ø§ÙØÙÙÙØ© ÙØ¥Ø¨ÙØ§ØºÙØ§ Ø¨ÙØ¶ÙØ ÙÙØ¬Ù
ÙØ¹.
+=======
+When a programmer is sure that a variable will never change, they can declare it with `const` to guarantee and communicate that fact to everyone.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
### Ø«ÙØ§Ø¨Øª ذات Ø§ÙØØ±Ù٠اÙÙØ¨ÙرÙ
+<<<<<<< HEAD
ÙÙØ§Ù Ù
Ù
ارسة شائعة ÙØ§Ø³ØªØ®Ø¯Ø§Ù
Ø§ÙØ«Ùابت ÙØ£Ø³Ù
اء Ù
ستعارة ÙÙÙÙÙ
Ø§ÙØªÙ ÙØµØ¹Ø¨ ØªØ°ÙØ±Ùا ÙØ§ÙÙ
عرÙÙØ© ÙØ¨Ù Ø§ÙØªÙÙÙØ°.
+=======
+There is a widespread practice to use constants as aliases for difficult-to-remember values that are known before execution.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
تتÙ
تسÙ
ÙØ© ÙØ°Ù Ø§ÙØ«Ùابت باستخداÙ
Ø§ÙØ£ØØ±Ù اÙÙØ¨Ùرة ÙØ§Ùشرطات Ø§ÙØ³ÙÙÙØ©.
@@ -290,16 +349,29 @@ alert(color); // #FF7F00
Ù
ØªÙ ÙØ¬Ø¨ Ø£Ù ÙØ³ØªØ®Ø¯Ù
Ø§ÙØØ±Ù٠اÙÙØ¨Ùر٠Ù٠تسÙ
ÙØ© Ø§ÙØ«Ùابت ÙÙ
ØªÙ ÙØ³ØªØ®Ø¯Ù
Ø§ÙØØ±ÙÙ Ø§ÙØ¹Ø§Ø¯ÙÙØ ÙÙØ§ Ø¨ÙØ§ ÙÙØ¶Ø ذÙÙ.
+<<<<<<< HEAD
Ø§ÙØ«Ø§Ø¨Øª ÙØ¹Ù٠أ٠ÙÙÙ
Ø© اÙÙ
ØªØºÙØ± ÙÙ ØªØªØºÙØ± أبداÙ. ÙÙÙÙ ÙÙØ§Ù Ø«ÙØ§Ø¨Øª Ù
Ø¹Ø±ÙØ© ÙØ¨Ù Ø§ÙØªÙÙÙØ° (Ù
Ø«Ù Ø§ÙØ±ÙÙ
Ø§ÙØ³Ø¯Ø§Ø³Ù Ø§ÙØ¹Ø´Ø±Ù ÙÙÙÙ Ø§ÙØ§ØÙ
ر) ÙÙÙØ§Ù Ø«ÙØ§Ø¨Øª *Ù
ØØ³Ùبة* ÙÙ ØØ§ÙØ© Ø§ÙØªØ´ØºÙÙ, Ø£Ø«ÙØ§Ø¡ Ø§ÙØªÙÙÙØ°, ÙÙÙÙ ÙØ§ ØªØªØºÙØ± ÙÙÙ
ØªÙØ§ Ø§ÙØ§ÙÙÙØ©.
عÙ٠سبÙ٠اÙÙ
ثاÙ:
+=======
+Being a "constant" just means that a variable's value never changes. But some constants are known before execution (like a hexadecimal value for red) and some constants are *calculated* in run-time, during the execution, but do not change after their initial assignment.
+
+For instance:
+
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
const pageLoadTime = /* اÙÙÙØª اÙÙØ§Ø²Ù
ÙØªØØ¶Ùر ØµÙØØ© اÙÙÙØ¨ */;
```
+<<<<<<< HEAD
ÙÙÙ
Ø© `pageLoadTime` ØºÙØ± Ù
عرÙÙ ÙÙ Ø¨Ø¯Ø§ÙØ© ØªØØ¶Ùر Ø§ÙØµÙØØ©, ÙØ°ÙÙ Ù
Ù Ø§ÙØ·Ø¨Ùع٠تسÙ
ÙØªÙا. ÙÙÙÙÙØ§ Ù
Ø§Ø²Ø§ÙØª ثابت ÙØ§ÙÙØ§ ÙÙ
ØªØªØºÙØ± بعد Ø§ÙØªØ¹Ø±ÙÙ.
بÙ
عÙ٠آخر Ø ØªÙØ³ØªØ®Ø¯Ù
Ø§ÙØ«Ùابت Ø§ÙØªÙ تØÙ
٠أسÙ
اء ÙØ¨Ùرة ÙÙØ· ÙØ£Ø³Ù
اء Ù
ستعارة ÙÙÙÙ
"Ø§ÙØ«Ø§Ø¨Øª Ø§ÙØªØ±Ù
ÙØ²".
+=======
+The value of `pageLoadTime` is not known before the page load, so it's named normally. But it's still a constant because it doesn't change after the assignment.
+
+In other words, capital-named constants are only used as aliases for "hard-coded" values.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## تسÙ
ÙØ© Ø§ÙØ§Ø´Ùاء بشÙ٠صØÙØ
@@ -307,18 +379,31 @@ const pageLoadTime = /* اÙÙÙØª اÙÙØ§Ø²Ù
ÙØªØØ¶Ùر ØµÙØØ© اÙÙÙØ¨
ÙØ¬Ø¨ Ø£Ù ÙÙÙÙ ÙØ§Ø³Ù
Ù
ØªØºÙØ± Ù
عÙÙ ÙØ§Ø¶Ø ÙÙØ§Ø¶Ø ÙØµÙ Ø§ÙØ¨ÙØ§ÙØ§Øª Ø§ÙØªÙ ÙØ®Ø²ÙÙØ§.
+<<<<<<< HEAD
تسÙ
ÙØ© اÙÙ
ØªØºÙØ±Ø§Øª تÙÙÙ ÙØ§ØØ¯Ø© Ù
٠أÙÙ
ÙØ£Ø¹Ùد اÙÙ
ÙØ§Ø±Ø§Øª ÙÙ Ø§ÙØ¨Ø±Ù
جÙ. ÙÙ
ÙÙ Ø£Ù ØªÙØ´Ù ÙÙ
ØØ© Ø³Ø±ÙØ¹Ø© Ø¹Ù Ø§ÙØ£Ø³Ù
اء اÙÙ
ØªØºÙØ±Ø© Ø§ÙØ±Ù
ز Ø§ÙØ°Ù ÙØªØ¨Ù Ù
بتدئ Ù
ÙØ§Ø¨Ù Ù
Ø·ÙØ± Ù
تÙ
رس.
Ø®ÙØ§Ù Ù
Ø´Ø±ÙØ¹ ØÙÙÙÙ, ÙØªÙ
ÙØ¶Ø§Ø¡ Ù
عظÙ
اÙÙÙØª Ù٠تعدÙÙ ÙØªÙØ³ÙØ¹ ÙØ§Ø¹Ø¯Ø© Ø§ÙØªØ¹ÙÙÙ
ات Ø§ÙØ¨Ø±Ù
Ø¬ÙØ© Ø§ÙØØ§ÙÙØ© Ø¨Ø¯ÙØ§Ù Ù
Ù ÙØªØ§Ø¨Ø© Ø´ÙØ¡ Ù
ÙÙØµÙ تÙ
اÙ
ÙØ§ ع٠ÙÙØ·Ø© Ø§ÙØµÙر. Ø¹ÙØ¯Ù
ا ÙØ¹Ùد Ø¥Ù٠بعض Ø§ÙØªØ¹ÙÙÙ
ات Ø§ÙØ¨Ø±Ù
Ø¬ÙØ© بعد اÙÙÙØ§Ù
Ø¨Ø´ÙØ¡ آخر ÙÙØªØ±Ø© Ù
٠اÙÙÙØª Ø ÙÙÙÙ Ù
Ù Ø§ÙØ£Ø³ÙÙ Ø¨ÙØ«Ùر Ø§ÙØ¹Ø«Ùر عÙ٠اÙÙ
عÙÙÙ
ات اÙÙ
صÙÙØ© Ø¬ÙØ¯Ùا. أ٠بÙ
عÙ٠آخر Ø Ø¹ÙØ¯Ù
ا ÙÙÙÙ ÙÙÙ
ØªØºÙØ±Ø§Øª أسÙ
اء Ø¬ÙØ¯Ø©.
+=======
+Variable naming is one of the most important and complex skills in programming. A glance at variable names can reveal which code was written by a beginner versus an experienced developer.
+
+In a real project, most of the time is spent modifying and extending an existing code base rather than writing something completely separate from scratch. When we return to some code after doing something else for a while, it's much easier to find information that is well-labelled. Or, in other words, when the variables have good names.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù
Ù ÙØ¶Ù٠خذ ÙÙØªÙ ÙÙ Ø§Ø®ØªÙØ§Ø± اسÙ
صØÙØ ÙÙÙ
ØªØºÙØ± ÙØ¨Ù تعرÙÙÙ. اÙÙÙØ§Ù
بذÙ٠سÙÙ ÙØ³Ø¯Ø¯ Ù٠بسخاء
بعض اÙÙÙØ§Ø¹Ø¯ Ø§ÙØ¬Ùدة ÙØ£ØªØ¨Ø§Ø¹Ùا ÙÙÙ :
+<<<<<<< HEAD
- أستخدÙ
أسÙ
اء Ù
ØªØ¹Ø§Ø±Ù Ø§ÙØ§Ùسا٠عÙÙÙØ§ Ù
ث٠`userName` ا٠`shoppingCart`.
- Ø§ÙØ§Ø¨ØªØ¹Ø§Ø¯ Ø¹Ù Ø§ÙØ§Ø®ØªØµØ§Ø±Ø§Øª Ø£Ù Ø§ÙØ£Ø³Ù
اء اÙÙØµÙرة Ù
ث٠`a`, `b`, `c`, Ø£ÙØ§ اذا ÙÙØª تعÙÙ
Ù
اذا ØªÙØ¹Ù.
- Ø§Ø¬Ø¹Ù Ø§ÙØ£Ø³Ù
اء ÙØµÙÙØ© ÙÙ
ÙØ¬Ø²Ø© Ø¥ÙÙ Ø£ÙØµÙ ØØ¯. Ø£Ù
Ø«ÙØ© ÙØ£Ø³Ù
اء Ø³ÙØ¦Ø© `data` Ù `value`. Ø§ÙØ§Ø³Ù
اء ÙØ°Ù ÙØ§ تعبر ع٠شئ. Ù
٠اÙÙ
ÙØ¨Ù٠استخداÙ
ÙØ§ ÙÙØ· إذا ÙØ§Ù Ø³ÙØ§Ù اÙÙÙØ¯ ÙØ¬Ø¹Ù Ù
٠اÙÙØ§Ø¶Ø بشÙÙ Ø§Ø³ØªØ«ÙØ§Ø¦Ù Ø§ÙØ¨ÙØ§ÙØ§Øª أ٠اÙÙÙÙ
Ø© Ø§ÙØªÙ ÙØ´Ùر Ø¥ÙÙÙØ§ اÙÙ
ØªØºÙØ±.
- ÙØ§Ù٠عÙÙ Ø§ÙØ´Ø±ÙØ· Ø¯Ø§Ø®Ù ÙØ±ÙÙÙ ÙÙ٠ذÙÙÙ. إذا ÙØ§Ù زائر اÙÙ
ÙÙØ¹ ÙØ³Ù
Ù "Ù
ستخدÙ
" Ø ÙÙØ¬Ø¨ عÙÙÙØ§ تسÙ
ÙØ© اÙÙ
ØªØºÙØ±Ø§Øª ذات Ø§ÙØµÙØ© `currentUser` ا٠`newUser` Ø¨Ø¯ÙØ§ Ù
٠`currentVisitor` ا٠`newManInTown`
+=======
+- Use human-readable names like `userName` or `shoppingCart`.
+- Stay away from abbreviations or short names like `a`, `b`, and `c`, unless you know what you're doing.
+- Make names maximally descriptive and concise. Examples of bad names are `data` and `value`. Such names say nothing. It's only okay to use them if the context of the code makes it exceptionally obvious which data or value the variable is referencing.
+- Agree on terms within your team and in your mind. If a site visitor is called a "user" then we should name related variables `currentUser` or `newUser` instead of `currentVisitor` or `newManInTown`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ØªØ¨Ø¯Ù Ø¨Ø³ÙØ·Ø©Ø Ù٠اÙÙØ§Ùع Ø ÙÙÙÙ Ø¥ÙØ´Ø§Ø¡ أسÙ
اء Ù
ØªØºÙØ±Ø© ÙØµÙÙØ© ÙÙ
ÙØ¬Ø²Ø© ÙÙØ³ ÙØ°ÙÙ. Ø£Ø°ÙØ¨ Ø®ÙÙÙØ§.
diff --git a/1-js/02-first-steps/05-types/article.md b/1-js/02-first-steps/05-types/article.md
index d555a8c24..4b54aa7a7 100644
--- a/1-js/02-first-steps/05-types/article.md
+++ b/1-js/02-first-steps/05-types/article.md
@@ -47,13 +47,23 @@ n = 12.345;
alert( "not a number" / 2 ); // NaN Ù
Ø«Ù ÙØ°Ù اÙÙØ³Ù
ة خاطئة
```
+<<<<<<< HEAD
`NaN` ÙØ²Ø¬Ø©. أ٠عÙ
ÙÙØ© تتÙ
عÙÙ `NaN` ترجع `NaN`:
+=======
+ `NaN` is sticky. Any further mathematical operation on `NaN` returns `NaN`:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
- alert( "not a number" / 2 + 5 ); // NaN
+ alert( NaN + 1 ); // NaN
+ alert( 3 * NaN ); // NaN
+ alert( "not a number" / 2 - 1 ); // NaN
```
+<<<<<<< HEAD
ÙØ°Ù٠إذا ÙØ¬Ø¯Øª `NaN` Ù٠أ٠Ù
ÙØ§Ù ÙÙ ØªØ¹Ø¨ÙØ± ØØ³Ø§Ø¨Ù ØªÙØªØ´Ø± Ù٠اÙÙØªÙجة بأÙÙ
ÙÙØ§.
+=======
+ So, if there's a `NaN` somewhere in a mathematical expression, it propagates to the whole result (there's only one exception to that: `NaN ** 0` is `1`).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```smart header="Ø§ÙØ¹Ù
ÙÙØ§Øª Ø§ÙØ±ÙØ§Ø¶ÙØ© Ø£Ù
ÙØ©"
اÙÙÙØ§Ù
Ø¨Ø§ÙØ±ÙØ§Ø¶ÙØ§Øª "Ø£Ù
Ù" ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ø¨Øª. ÙØ³ØªØ·Ùع اÙÙÙØ§Ù
بأ٠شئ: اÙÙØ³Ù
Ø© عÙÙ ØµÙØ± Ù Ù
عاÙ
ÙØ© اÙÙØµÙص Ø§ÙØºÙر Ø§ÙØ±ÙÙ
ÙØ© عÙ٠أÙÙØ§ Ø£Ø±ÙØ§Ù
Ù Ø¥ÙØ®.
@@ -65,11 +75,28 @@ n = 12.345;
Ø³ÙØ±Ù اÙÙ
Ø²ÙØ¯ Ù
Ù Ø§ÙØªØ¹Ø§Ù
Ù Ù
ع Ø§ÙØ£Ø±ÙاÙ
Ø®ÙØ§Ù ÙØ°Ø§ اÙÙØµÙ .
-## BigInt
+## BigInt [#bigint-type]
+<<<<<<< HEAD
ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±ÙØ¨ØªØ Ø§ÙÙÙØ¹ "number" ÙØ§ ÙÙ
Ø«Ù Ø§ÙØ£Ø¹Ø¯Ø§Ø¯ Ø§ÙØµØÙØØ© Ø£ÙØ¨Ø± Ù
Ù (253-1) (Ù ÙÙ `9007199254740991`)Ø Ø£Ù Ø£ÙÙ Ù
Ù -(-253-1) ÙÙØ£Ø±ÙاÙ
Ø§ÙØ³Ø§Ùبة. Ø¥ÙÙØ§ ÙÙÙØ¯ ÙÙÙØ© ÙØ§ØªØ¬Ø© ع٠تÙ
Ø«ÙÙÙÙ
Ø§ÙØ¯Ø§Ø®ÙÙ.
ÙÙ
عظÙ
Ø§ÙØ£ØºØ±Ø§Ø¶ ÙØ°Ø§ ÙÙÙÙØ ÙÙÙ Ù٠بعض Ø§ÙØ£ØÙØ§Ù ÙØØªØ§Ø¬ ÙØ£Ø±ÙاÙ
ÙØ¨Ùرة ØÙØ§Ù Ø Ø¹Ù٠سبÙ٠اÙÙ
ثاÙ. ÙÙØªØ´ÙÙØ± Ø£Ù Ø§ÙØ·Ùابع Ø§ÙØ²Ù
ÙÙØ© Ø§ÙØ¯ÙÙÙØ© ÙÙÙ
ÙÙØ±Ù ثاÙÙØ©.
+=======
+In JavaScript, the "number" type cannot safely represent integer values larger than (253-1) (that's `9007199254740991`), or less than -(253-1) for negatives.
+
+To be really precise, the "number" type can store larger integers (up to 1.7976931348623157 * 10308), but outside of the safe integer range ±(253-1) there'll be a precision error, because not all digits fit into the fixed 64-bit storage. So an "approximate" value may be stored.
+
+For example, these two numbers (right above the safe range) are the same:
+
+```js
+console.log(9007199254740991 + 1); // 9007199254740992
+console.log(9007199254740991 + 2); // 9007199254740992
+```
+
+So to say, all odd integers greater than (253-1) can't be stored at all in the "number" type.
+
+For most purposes ±(253-1) range is quite enough, but sometimes we need the entire range of really big integers, e.g. for cryptography or microsecond-precision timestamps.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
`BigInt` تÙ
ت Ø¥Ø¶Ø§ÙØ© اÙÙÙØ¹ Ù
Ø¤Ø®Ø±ÙØ§ Ø¥Ù٠اÙÙØºØ© ÙØªÙ
Ø«ÙÙ Ø§ÙØ£Ø¹Ø¯Ø§Ø¯ Ø§ÙØµØÙØØ© ذات Ø§ÙØ·Ù٠اÙÙØ¨Ùر.
@@ -82,6 +109,7 @@ const bigInt = 1234567890123456789012345678901234567890n;
بÙ
ا Ø£Ù Ø£Ø±ÙØ§Ù
Ù
Ù ÙÙØ¹ `BigInt` ÙØØªØ§Ø¬ÙØ§ ÙØ§Ø¯Ø±Ø§Ù Ø ÙÙ ÙØªÙ
ØªØºØ·ÙØªÙا ÙÙØ§ Ø ÙÙ٠سÙÙØ±Ø¯ ÙÙØ§ ÙØµÙ Ù
خصص . Ø§ÙØ±Ø£Ù Ø¹ÙØ¯Ù
ا ØªØØªØ§Ø¬ ÙÙ
Ø«Ù ÙØ°Ù Ø§ÙØ£Ø±ÙاÙ
اÙÙØ¨Ùرة.
+<<<<<<< HEAD
```smart header="Ù
شاÙÙ ØªÙØ§ÙÙÙØ©"
Ø§ÙØ£Ù `BigInt` Ù
ØªÙØ§ÙÙ Ù
ع ÙØ§ÙرÙÙÙØ³/ÙØ±ÙÙ
/Ø§ÙØ¯Ø¬/Ø³ÙØ§Ø±Ù ØÙÙÙ ÙÙØ³Øª Ù
ØªÙØ§ÙÙØ© Ù
ع Ø¥ÙØªØ±Ùت Ø§ÙØ³Ø¨ÙÙØ±Ø±
```
@@ -89,6 +117,9 @@ const bigInt = 1234567890123456789012345678901234567890n;
You can check [*MDN* BigInt compatibility table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility) to know which versions of a browser are supported.
## اÙÙØµ
+=======
+## String
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
اÙÙØµ ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØªÙ
Ø¥ØØ§Ø·ØªÙ Ø¨Ø¹ÙØ§Ù
ات ØªÙØµÙص.
@@ -211,6 +242,7 @@ alert(age); // "undefined"
## The typeof operator [#type-typeof]
+<<<<<<< HEAD
Ù
عاÙ
Ù `typeof` ÙØ±Ø¬Ø¹ ÙÙØ¹ ÙÙÙ
Ø© اÙÙ
Ø¯Ø®ÙØ§Øª. Ø¥ÙÙ Ù
ÙÙØ¯ Ø¹ÙØ¯Ù
ا ÙØ±Ùد Ù
Ø¹Ø§ÙØ¬Ø© ÙÙÙ
Ù
٠أÙÙØ§Ø¹ Ù
ختÙÙØ© Ø¨Ø¥Ø®ØªÙØ§Ù Ø£Ù ÙÙ
جرد إجراد ÙØØµ Ø³Ø±ÙØ¹ ÙÙÙÙØ¹ .
Ø¥ÙÙ ÙØ¯Ø¹Ù
ÙÙØ¹ÙÙ Ù
Ù Ø¨ÙØ§Ø¡ اÙÙÙØ¯:
@@ -221,6 +253,11 @@ alert(age); // "undefined"
بÙÙÙ
ات Ø£Ø®Ø±Ù Ø Ø¥ÙÙØ§ تعÙ
٠بأÙÙØ§Ø³ أ٠بدÙ٠أÙÙØ§Ø³. اÙÙØªÙجة ستÙÙÙ ÙØ§ØØ¯Ø©.
إستدعاء `typeof x` ÙØ±Ø¬Ø¹ ÙØµ بإسÙ
ÙÙØ¹ اÙÙÙÙ
Ø©:
+=======
+The `typeof` operator returns the type of the operand. It's useful when we want to process values of different types differently or just want to do a quick check.
+
+A call to `typeof x` returns a string with the type name:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
typeof undefined // "undefined"
@@ -250,14 +287,33 @@ typeof alert // "function" (3)
Ø§ÙØ«Ùاث Ø³Ø·ÙØ± Ø§ÙØ£Ø®Ùرة ÙØ¯ ØªØØªØ§Ø¬ ÙØªÙØ¶ÙØ إضاÙÙ:
+<<<<<<< HEAD
1. `Math` ÙØ§Ø¦Ù Ù
دÙ
ج داخÙÙØ§Ù ÙØªØ¯Ø¹ÙÙ
Ø§ÙØ¹Ù
ÙÙØ§Øª Ø§ÙØ±ÙØ§Ø¶ÙØ©. Ø³ÙØªØ¹ÙÙ
Ù Ù٠اÙÙØµÙ . ÙÙØ§Ø ÙØ®Ø¯Ù
ÙÙØ· ÙÙ
ثا٠ÙÙÙØ§Ø¦Ù.
2. ÙØªÙجة `typeof null` ÙÙ `"object"`. ÙØ°Ø§ رسÙ
ÙØ§Ù ÙØ¹ØªØ¨Ø± خطأ Ù٠سÙÙÙ `typeof` Ø ÙØ£ØªÙ Ù
Ù Ø§ÙØ£ÙاÙ
Ø§ÙØ£ÙÙÙ ÙØ¬Ø§Ùا Ø³ÙØ±Ø¨Øª ÙØªÙ
Ø§ÙØÙØ§Ø¸ عÙÙÙ Ù
Ù Ø£Ø¬Ù Ø§ÙØªÙاÙÙÙØ©. ÙØ·Ø¹Ø§Ù `null` ÙÙØ³ ÙØ§Ø¦Ù. Ø¥ÙÙ ÙÙÙ
Ø© خاصة بÙÙØ¹ Ù
ÙÙØµÙ خاص.
3. ÙØªÙجة `typeof alert` ÙÙ `"function"`Ø ÙØ£Ù `alert` Ø¯Ø§ÙØ©. Ø³ÙØ¯Ø±Ø³ Ø§ÙØ¯Ùا٠Ù٠اÙÙØµÙ٠اÙÙØ§Ø¯Ù
Ø© ÙÙÙØ§Ù Ø³ÙØ±Ù Ø£ÙÙ ÙØ§ ØªÙØ¬Ø¯ ÙÙØ¹ خاص "Ø¯Ø§ÙØ©" ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ø¨Øª. Ø§ÙØ¯ÙØ§Ù Ø§ÙØ¯ÙØ§Ù ØªÙØªÙ
Ù ÙÙÙÙØ¹ ÙØ§Ø¦Ù. ÙÙÙ `typeof` تعاÙ
ÙÙÙ
بشÙÙ Ù
ختÙÙØ ÙØ±Ø¬Ø¹ `"Ø¯Ø§ÙØ©"`. ÙØ°Ø§ Ø£ÙØ¶Ø§Ù ÙØ£ØªÙ Ù
Ù Ø§ÙØ£ÙاÙ
Ø§ÙØ£ÙÙÙ ÙØ¬Ø§Ùا Ø³ÙØ±Ø¨Øª. ÙÙÙØ§ÙØ Ù
Ø«Ù ÙØ°Ø§ Ø§ÙØ³ÙÙÙ ØºÙØ± صØÙØØ ÙÙÙ ÙØ¯ ÙÙÙÙ Ù
ÙØ§Ø¦Ù
Ù٠اÙÙ
Ù
ارسة.
## Ø®ÙØ§ØµØ©
+=======
+1. `Math` is a built-in object that provides mathematical operations. We will learn it in the chapter . Here, it serves just as an example of an object.
+2. The result of `typeof null` is `"object"`. That's an officially recognized error in `typeof`, coming from very early days of JavaScript and kept for compatibility. Definitely, `null` is not an object. It is a special value with a separate type of its own. The behavior of `typeof` is wrong here.
+3. The result of `typeof alert` is `"function"`, because `alert` is a function. We'll study functions in the next chapters where we'll also see that there's no special "function" type in JavaScript. Functions belong to the object type. But `typeof` treats them differently, returning `"function"`. That also comes from the early days of JavaScript. Technically, such behavior isn't correct, but can be convenient in practice.
+
+```smart header="The `typeof(x)` syntax"
+You may also come across another syntax: `typeof(x)`. It's the same as `typeof x`.
+
+To put it clear: `typeof` is an operator, not a function. The parentheses here aren't a part of `typeof`. It's the kind of parentheses used for mathematical grouping.
+
+Usually, such parentheses contain a mathematical expression, such as `(2 + 2)`, but here they contain only one argument `(x)`. Syntactically, they allow to avoid a space between the `typeof` operator and its argument, and some people like it.
+
+Some people prefer `typeof(x)`, although the `typeof x` syntax is much more common.
+```
+
+## Summary
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ¬Ø¯ 8 Ø£ÙÙØ§Ø¹ ÙÙØ¨ÙØ§ÙØ§Øª ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ø¨Øª.
+<<<<<<< HEAD
- `number` ÙÙØ£Ø±ÙاÙ
Ù
٠أ٠ÙÙØ¹: صØÙØ Ø£Ù Ø¹Ø´Ø±ÙØ Ø§ÙØ£Ø¹Ø¯Ø§Ø¯ Ø§ÙØµØÙØØ© Ù
ØØ¯Ùدة ب ±(253-1).
- `bigint` Ù٠عدد صØÙØ Ø·ÙÙÙ ÙØ¨Ùر.
- `string` ÙÙÙØµÙص. اÙÙØµ ÙØ¯ ÙØØªÙ٠عÙÙ ØµÙØ± ØØ±Ù Ø£Ù Ø£ÙØ«Ø±Ø ÙØ§ ÙÙØ¬Ø¯ ÙÙØ¹ Ù
ÙÙØµÙ ÙÙØØ±Ù Ø§ÙÙØ§ØØ¯.
@@ -266,11 +322,29 @@ typeof alert // "function" (3)
- `undefined` ÙÙÙÙÙ
ØºÙØ± اÙÙ
عÙÙØ© -- ÙÙØ¹ ÙØ§Ø¦Ù
بذات٠ÙÙ ÙÙÙ
Ø© ÙØ§ØØ¯Ø© ÙÙØ· `undefined`.
- `object` Ù
٠أج٠ÙÙØ§ÙÙ Ø¨ÙØ§Ùات Ù
Ø¹ÙØ¯Ø©.
- `symbol` Ù
٠أج٠Ù
Ø¹Ø±ÙØ§Øª ÙØ±Ùدة.
+=======
+- Seven primitive data types:
+ - `number` for numbers of any kind: integer or floating-point, integers are limited by ±(253-1).
+ - `bigint` for integer numbers of arbitrary length.
+ - `string` for strings. A string may have zero or more characters, there's no separate single-character type.
+ - `boolean` for `true`/`false`.
+ - `null` for unknown values -- a standalone type that has a single value `null`.
+ - `undefined` for unassigned values -- a standalone type that has a single value `undefined`.
+ - `symbol` for unique identifiers.
+- And one non-primitive data type:
+ - `object` for more complex data structures.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù
عاÙ
Ù `typeof` ÙØ³Ù
Ø ÙÙØ§ بÙ
Ø¹Ø±ÙØ© ÙÙØ¹ Ø§ÙØ¨ÙØ§ÙØ§Øª اÙÙ
ÙØ¬Ùدة بداخ٠اÙÙ
ØªØºÙØ±Ø©.
+<<<<<<< HEAD
- ÙÙ Ø´ÙÙØ§Ù: `typeof x` Ø£Ù `typeof(x)`.
- ÙØ±Ø¬Ø¹ ÙØµ بإسÙ
ÙÙØ¹ Ø§ÙØ¨ÙØ§ÙØ§ØªØ Ù
ث٠`"string"`.
- Ù
٠أج٠`null` ÙØ±Ø¬Ø¹ `"object"` - ÙØ°Ø§ خطأ Ù٠اÙÙØºØ©Ø Ø¥ÙÙ ÙÙØ³ ÙÙ Ø§ÙØÙÙÙØ© ÙØ§Ø¦Ù.
+=======
+- Usually used as `typeof x`, but `typeof(x)` is also possible.
+- Returns a string with the name of the type, like `"string"`.
+- For `null` returns `"object"` -- this is an error in the language, it's not actually an object.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù٠اÙÙØµÙ٠اÙÙØ§Ø¯Ù
Ø© Ø³ÙØ±Ùز عÙ٠اÙÙÙÙ
Ø§ÙØ¨Ø¯Ø§Ø¦ÙØ© ÙØ¹ÙدÙ
ا ÙÙÙÙ Ù
تأÙÙÙÙ Ù
عاÙÙ
Ø Ø³ÙØªØ¬Ù ÙÙÙØ§Ø¦Ùات.
diff --git a/1-js/02-first-steps/07-type-conversions/article.md b/1-js/02-first-steps/07-type-conversions/article.md
index 81e9efc25..83dc52298 100644
--- a/1-js/02-first-steps/07-type-conversions/article.md
+++ b/1-js/02-first-steps/07-type-conversions/article.md
@@ -6,8 +6,13 @@
ÙÙØ§Ù Ø£ÙØ¶Ø§Ù ØØ§Ùات ÙØØªØ§Ø¬ Ø¥ÙÙ ØªØµØ±ÙØ تØÙÙ٠اÙÙÙÙ
Ø© Ø¥Ù٠اÙÙÙØ¹ اÙÙ
Ø·ÙÙØ¨.
+<<<<<<< HEAD
```smart header="ÙØ§ ÙØªØØ¯Ø« ع٠objects بعد"
ÙÙ ÙØ°Ø§ اÙÙØµÙØ ÙÙ ÙØºØ·Ù اÙÙØ§Ø¦Ùات. Ø§ÙØ¢Ù سÙÙ ÙØªØØ¯Ø« Ø¹Ù Ø§ÙØ£ÙÙØ§Ø¹ Ø§ÙØ£Ø³Ø§Ø³ÙØ©.
+=======
+```smart header="Not talking about objects yet"
+In this chapter, we won't cover objects. For now, we'll just be talking about primitives.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙÙ
ا Ø¨Ø¹Ø¯Ø Ø¨Ø¹Ø¯ Ø£Ù ÙØªØ¹ÙÙ
ع٠اÙÙØ§Ø¦ÙØ§ØªØ ÙÙ ÙØ°Ø§ اÙÙØµÙ Ø³ÙØ±Ù ÙÙÙ ØªØªÙØ§Ø¦Ù
اÙÙØ§Ø¦Ùات ÙÙÙ.
```
@@ -34,7 +39,11 @@ alert(typeof value); // string
## Ø§ÙØªØÙÙÙ Ø§ÙØ±ÙÙ
Ù
+<<<<<<< HEAD
Ø§ÙØªØÙÙ٠إÙ٠رÙÙ
ÙØªÙ
Ø£ÙØªÙÙ
اتÙÙÙØ§Ù Ù٠اÙÙ
عاÙ
ÙØ§Øª ÙØ§ÙØªØ¹Ø¨ÙØ±Ø§Øª Ø§ÙØ±ÙØ§Ø¶ÙØ©.
+=======
+Numeric conversion in mathematical functions and expressions happens automatically.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
عÙ٠سبÙ٠اÙÙ
Ø«Ø§ÙØ ÙÙ ØØ§ÙØ© اÙÙØ³Ù
Ø© `/` Ø¹ÙØ¯Ù
ا ÙØªÙ
تطبÙÙÙØ§ عÙÙ ÙÙØ¹ ØºÙØ± رÙÙ
Ù:
@@ -70,7 +79,11 @@ alert(age); // NaNØ Ø§ÙØªØÙÙÙ ÙØ´Ù
|`undefined`|`NaN`|
|`null`|`0`|
|true and false | `1` and `0` |
+<<<<<<< HEAD
| `string` | اÙÙ
Ø³Ø§ØØ§Øª Ø§ÙØ¨Ùضاء ÙÙ Ø§ÙØ¨Ø¯Ø§ÙØ© ÙØ§ÙÙÙØ§ÙØ© ÙØªÙ
Ø¥Ø²Ø§ÙØªÙا. Ù٠باÙ٠اÙÙØµ ÙØ§Ø±ØºØ اÙÙØªÙجة ÙÙ `0`. ØºÙØ± ذÙÙØ Ø§ÙØ±ÙÙ
"ÙØªÙ
ÙØ±Ø§Ø¦ØªÙ" Ù
٠اÙÙØµ. أ٠خطأ ÙØ¹Ø·Ù`NaN`. |
+=======
+| `string` | Whitespaces (includes spaces, tabs `\t`, newlines `\n` etc.) from the start and end are removed. If the remaining string is empty, the result is `0`. Otherwise, the number is "read" from the string. An error gives `NaN`. |
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø£Ù
Ø«ÙØ©:
@@ -130,7 +143,11 @@ alert( Boolean(" ") ); // اÙÙ
Ø³Ø§ÙØ§ØªØ Ø£ÙØ¶Ø§Ù true (Ø£Ù ÙØµ ØºÙØ±
|`undefined`|`NaN`|
|`null`|`0`|
|true / false | `1 / 0` |
+<<<<<<< HEAD
| `string` | ÙØªÙ
ÙØ±Ø§Ø¡Ø© اÙÙØµ "ÙÙ
ا ÙÙ"ØØ§ÙÙ
Ø³Ø§ÙØ§Øª Ø§ÙØ¨Ùضاء Ù
Ù Ø§ÙØ¬Ø§ÙبÙÙ ÙØªÙ
تجاÙÙÙØ§. اÙÙØµ اÙÙØ§Ø±Øº ÙØµØ¨Ø `0`. Ø§ÙØ®Ø·Ø£ `NaN`. |
+=======
+| `string` | The string is read "as is", whitespaces (includes spaces, tabs `\t`, newlines `\n` etc.) from both sides are ignored. An empty string becomes `0`. An error gives `NaN`. |
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
**`Ø§ÙØªØÙÙÙØ§Øª اÙÙ
ÙØ·ÙÙØ©`** -- ÙØØ¯Ø« Ù٠اÙÙ
عاÙ
ÙØ§Øª اÙÙ
ÙØ·ÙÙØ©. ÙØªÙ
تÙÙÙØ°Ù ع٠طرÙÙ `Boolean(value)`.
diff --git a/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
index 02dd6a6c4..098c31b24 100644
--- a/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
+++ b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
@@ -16,10 +16,20 @@ undefined + 1 = NaN // (6)
" \t \n" - 2 = -2 // (7)
```
+<<<<<<< HEAD
1. Ø§ÙØ¥Ø¶Ø§ÙØ© Ø¨Ø³ÙØ³ÙØ© "" + 1` تØÙÙ `1` Ø¥ÙÙ Ø³ÙØ³ÙØ©:` "" + 1 = "1" `Ø ÙØ¨Ø¹Ø¯ ذÙÙ ÙØ¯ÙÙØ§" 1 "+ 0` Ø ÙØªÙ
تطبÙÙ ÙÙØ³ اÙÙØ§Ø¹Ø¯Ø©.
2. ÙØ¹Ù
Ù Ø§ÙØ·Ø±Ø `-` (Ù
ث٠Ù
عظÙ
عÙ
ÙÙØ§Øª Ø§ÙØ±ÙØ§Ø¶ÙØ§Øª) Ù
ع Ø§ÙØ£Ø±ÙاÙ
ÙÙØ· Ø ÙÙÙ ÙØÙÙ Ø³ÙØ³ÙØ© ÙØ§Ø±ØºØ©" "" Ø¥ÙÙ "0".
3. Ø§ÙØ¥Ø¶Ø§ÙØ© Ø¨Ø³ÙØ³ÙØ© ØªÙØÙ Ø§ÙØ±ÙÙ
`5` Ø¨Ø§ÙØ³ÙØ³ÙØ©.
4. ÙØªØÙÙ Ø§ÙØ·Ø±Ø دائÙ
ÙØ§ Ø¥ÙÙ Ø£Ø±ÙØ§Ù
Ø ÙØ°ÙÙ ÙØ¬Ø¹Ù "-9" `رÙÙ
ÙØ§ -9` (تجاÙ٠اÙÙ
Ø³Ø§ÙØ§Øª ØÙÙÙ).
5. ÙØµØ¨Ø "null" "0" بعد Ø§ÙØªØÙÙÙ Ø§ÙØ±ÙÙ
Ù.
6. ÙØµØ¨Ø "ØºÙØ± Ù
عرÙÙ" "NaN" بعد Ø§ÙØªØÙÙÙ Ø§ÙØ±ÙÙ
Ù.
-7. ÙØªÙ
ÙØ·Ø¹ Ø£ØØ±Ù اÙÙ
Ø³Ø§ÙØ© Ù
Ù Ø¨Ø¯Ø§ÙØ© Ø§ÙØ³ÙØ³ÙØ© ÙÙÙØ§ÙØªÙØ§ Ø¹ÙØ¯ تØÙÙÙ Ø³ÙØ³ÙØ© Ø¥Ù٠رÙÙ
. تتÙÙÙ Ø§ÙØ³ÙØ³ÙØ© بأÙÙ
ÙÙØ§ ÙÙØ§ Ù
Ù Ø£ØØ±Ù Ù
Ø³Ø§ÙØ© Ø Ù
ث٠`\ t` Ù` \ n` ÙÙ
Ø³Ø§ÙØ© "Ø¹Ø§Ø¯ÙØ©" بÙÙÙÙ
ا. ÙØ°Ø§ Ø Ø¹Ù٠غرار Ø§ÙØ³ÙØ³ÙØ© اÙÙØ§Ø±ØºØ© Ø ØªØµØ¨Ø `0`.
\ No newline at end of file
+7. ÙØªÙ
ÙØ·Ø¹ Ø£ØØ±Ù اÙÙ
Ø³Ø§ÙØ© Ù
Ù Ø¨Ø¯Ø§ÙØ© Ø§ÙØ³ÙØ³ÙØ© ÙÙÙØ§ÙØªÙØ§ Ø¹ÙØ¯ تØÙÙÙ Ø³ÙØ³ÙØ© Ø¥Ù٠رÙÙ
. تتÙÙÙ Ø§ÙØ³ÙØ³ÙØ© بأÙÙ
ÙÙØ§ ÙÙØ§ Ù
Ù Ø£ØØ±Ù Ù
Ø³Ø§ÙØ© Ø Ù
ث٠`\ t` Ù` \ n` ÙÙ
Ø³Ø§ÙØ© "Ø¹Ø§Ø¯ÙØ©" بÙÙÙÙ
ا. ÙØ°Ø§ Ø Ø¹Ù٠غرار Ø§ÙØ³ÙØ³ÙØ© اÙÙØ§Ø±ØºØ© Ø ØªØµØ¨Ø `0`.
+=======
+1. The addition with a string `"" + 1` converts `1` to a string: `"" + 1 = "1"`, and then we have `"1" + 0`, the same rule is applied.
+2. The subtraction `-` (like most math operations) only works with numbers, it converts an empty string `""` to `0`.
+3. The addition with a string appends the number `5` to the string.
+4. The subtraction always converts to numbers, so it makes `" -9 "` a number `-9` (ignoring spaces around it).
+5. `null` becomes `0` after the numeric conversion.
+6. `undefined` becomes `NaN` after the numeric conversion.
+7. Space characters are trimmed off string start and end when a string is converted to a number. Here the whole string consists of space characters, such as `\t`, `\n` and a "regular" space between them. So, similarly to an empty string, it becomes `0`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/02-first-steps/08-operators/article.md b/1-js/02-first-steps/08-operators/article.md
index f3b7469c2..6f15cb1e6 100644
--- a/1-js/02-first-steps/08-operators/article.md
+++ b/1-js/02-first-steps/08-operators/article.md
@@ -50,24 +50,37 @@
عÙ٠سبÙ٠اÙÙ
ثاÙ:
```js run
-alert( 5 % 2 ); // 1, a remainder of 5 divided by 2
-alert( 8 % 3 ); // 2, a remainder of 8 divided by 3
+alert( 5 % 2 ); // 1, the remainder of 5 divided by 2
+alert( 8 % 3 ); // 2, the remainder of 8 divided by 3
+alert( 8 % 4 ); // 0, the remainder of 8 divided by 4
```
### Ø§ÙØ¶Ø±Ø¨ Ø§ÙØ£Ø³Ù **
+<<<<<<< HEAD
عاÙ
Ù Ø§ÙØ¶Ø±Ø¨ Ø§ÙØ£Ø³Ù `a ** b` ÙÙÙÙ
بضرب Ø§ÙØ±ÙÙ
`a` ÙÙ ÙÙØ³Ù عدد `b` Ù
٠اÙÙ
رات
+=======
+The exponentiation operator `a ** b` raises `a` to the power of `b`.
+
+In school maths, we write that as ab.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
عÙ٠سبÙ٠اÙÙ
ثاÙ:
```js run
-alert( 2 ** 2 ); // 4 (2 multiplied by itself 2 times)
-alert( 2 ** 3 ); // 8 (2 * 2 * 2, 3 times)
-alert( 2 ** 4 ); // 16 (2 * 2 * 2 * 2, 4 times)
+alert( 2 ** 2 ); // 2² = 4
+alert( 2 ** 3 ); // 2³ = 8
+alert( 2 ** 4 ); // 2â´ = 16
```
+<<<<<<< HEAD
Ù
٠اÙÙØ§ØÙØ© Ø§ÙØ±ÙØ§Ø¶ÙØ§ØªÙØ© Ø§ÙØ¶Ø±Ø¨ Ø§ÙØ£Ø³Ù ÙØ³ØªØ®Ø¯Ù
Ø£ÙØ¶Ø§ Ù
ع Ø§ÙØ£Ø±ÙاÙ
ØºÙØ± Ø§ÙØµØÙØØ©. عÙ٠سبÙ٠اÙÙ
Ø«Ø§Ù Ø§ÙØ¬Ø°Ø± Ø§ÙØªØ±Ø¨Ùع٠Ù٠ضرب أس٠بÙÙÙ
Ø©
`1/2`:
+=======
+Just like in maths, the exponentiation operator is defined for non-integer numbers as well.
+
+For example, a square root is an exponentiation by ½:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
alert( 4 ** (1/2) ); // 2 (power of 1/2 is the same as a square root)
@@ -77,7 +90,11 @@ alert( 8 ** (1/3) ); // 2 (power of 1/3 is the same as a cubic root)
## Ø¥Ø¶Ø§ÙØ© اÙÙÙÙ
ات ÙØ³ÙØ§Ø³Ù Ø§ÙØØ±Ù٠بعاÙ
Ù Ø§ÙØ¥Ø¶Ø§ÙØ© +
+<<<<<<< HEAD
ÙÙØ§ ÙØªØ¹Ø±Ù عÙÙ Ù
Ù
ÙØ²Ø§Øª Ø¹ÙØ§Ù
٠اÙÙØºØ© Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØ§ÙØªÙ ØªØªØ¬Ø§ÙØ² Ø§ÙØØ³Ø§Ø¨ اÙÙ
درسÙ
+=======
+Let's meet the features of JavaScript operators that are beyond school arithmetics.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¹Ø§Ø¯Ø©Ø Ø¹Ø§Ù
Ù Ø§ÙØ¥Ø¶Ø§ÙØ© "+" ÙÙÙÙ
بجÙ
ع Ø§ÙØ£Ø±ÙاÙ
@@ -198,6 +215,7 @@ alert( +apples + +oranges ); // 5
| Ø§ÙØ£Ø³Ø¨ÙÙØ© | Ø§ÙØ§Ø³Ù
| تسجÙÙ |
| ------------ | ------ | ------ |
| ... | ... | ... |
+<<<<<<< HEAD
| 17 | Ø£ØØ§Ø¯Ù زائد | `+` |
| 17 | ÙÙÙ Ø£ØØ§Ø¯Ù | `-` |
| 16 | Ø§ÙØ£Ø³Ù | `**` |
@@ -210,10 +228,28 @@ alert( +apples + +oranges ); // 5
| ... | ... | ... |
ÙÙ
ا ÙØ±Ù Ø ÙØ¥Ù "unary plus" ÙÙØ§ Ø£ÙÙÙÙØ© "17" ÙÙ٠أعÙÙ Ù
Ù "13" ÙÙ "add" (Ø«ÙØ§Ø¦Ù زائد). ÙÙØ°Ø§ Ø§ÙØ³Ø¨Ø¨ Ø ÙÙ ØªØ¹Ø¨ÙØ± "+ apples + + oranges" Ø ØªØ¹Ù
Ù Ø§ÙØ¥ÙØ¬Ø§Ø¨ÙØ§Øª Ø§ÙØ£ØØ§Ø¯ÙØ© ÙØ¨Ù Ø§ÙØ¥Ø¶Ø§ÙØ©.
+=======
+| 14 | unary plus | `+` |
+| 14 | unary negation | `-` |
+| 13 | exponentiation | `**` |
+| 12 | multiplication | `*` |
+| 12 | division | `/` |
+| 11 | addition | `+` |
+| 11 | subtraction | `-` |
+| ... | ... | ... |
+| 2 | assignment | `=` |
+| ... | ... | ... |
+
+As we can see, the "unary plus" has a priority of `14` which is higher than the `11` of "addition" (binary plus). That's why, in the expression `"+apples + +oranges"`, unary pluses work before the addition.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## Ø§ÙØªØ¹ÙÙÙ
+<<<<<<< HEAD
Ø¯Ø¹ÙØ§ ÙÙØ§ØØ¸ أ٠اÙÙ
ÙÙ
Ø© `=` ÙÙ Ø£ÙØ¶Ùا عاÙ
Ù. ÙÙÙ Ù
درجة Ù٠جدÙÙ Ø§ÙØ£Ø³Ø¨ÙÙØ© بأÙÙÙÙØ© Ù
ÙØ®Ùضة Ø¬Ø¯ÙØ§ ÙÙ `3`.
+=======
+Let's note that an assignment `=` is also an operator. It is listed in the precedence table with the very low priority of `2`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ°Ø§ Ø§ÙØ³Ø¨Ø¨ Ø Ø¹ÙØ¯Ù
ا ÙÙÙÙ
بتعÙÙÙ Ù
ØªØºÙØ± Ø Ù
ث٠`x = 2 * 2 + 1` Ø ØªØªÙ
Ø§ÙØØ³Ø§Ø¨Ø§Øª Ø£ÙÙØ§Ù Ø«Ù
ÙØªÙ
تÙÙÙÙ
` = `Ø ÙØªØ®Ø²Ù٠اÙÙØªÙجة ÙÙ` x`.
@@ -270,7 +306,11 @@ alert( c ); // 4
ÙØªÙ
تÙÙÙÙ
Ø§ÙØªØ¹ÙÙÙØ§Øª اÙÙ
تتابعة Ù
٠اÙÙÙ
Ù٠إÙ٠اÙÙØ³Ø§Ø±. Ø£ÙÙØ§Ù Ø ÙØªÙ
تÙÙÙÙ
Ø§ÙØªØ¹Ø¨Ùر اÙÙ
ÙØ¬Ùد ÙÙ Ø£ÙØµÙ اÙÙÙ
ÙÙ `2 + 2` Ø«Ù
ÙØªÙ
تعÙÙÙÙ ÙÙÙ
ØªØºÙØ±Ø§Øª اÙÙ
ÙØ¬Ùدة عÙ٠اÙÙØ³Ø§Ø±:` c` Ù` b` Ù` a`. Ù٠اÙÙÙØ§ÙØ© Ø ØªØ´ØªØ±Ù Ø¬Ù
ÙØ¹ اÙÙ
ØªØºÙØ±Ø§Øª ÙÙ ÙÙÙ
Ø© ÙØ§ØØ¯Ø©.
+<<<<<<< HEAD
Ù
رة Ø£Ø®Ø±Ù Ø ÙØ£ØºØ±Ø§Ø¶ سÙÙÙØ© اÙÙØ±Ø§Ø¡Ø© Ø Ù
Ù Ø§ÙØ£ÙØ¶Ù ØªÙØ³ÙÙ
ÙØ°Ù Ø§ÙØ´Ùرة Ø¥Ù٠بضعة أسطر:
+=======
+Once again, for the purposes of readability it's better to split such code into a few lines:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
c = 2 + 2;
@@ -309,9 +349,9 @@ alert( n ); // 14
```js run
let n = 2;
-n *= 3 + 5;
+n *= 3 + 5; // right part evaluated first, same as n *= 8
-alert( n ); // 16 (right part evaluated first, same as n *= 8)
+alert( n ); // 16
```
## Ø§ÙØ²Ùادة / اÙÙÙØµØ§Ù
@@ -442,7 +482,11 @@ counter++;
- RIGHT SHIFT ( `>>` )
- ZERO-FILL RIGHT SHIFT ( `>>>` )
+<<<<<<< HEAD
ÙØ§Ø¯Ø±Ùا Ù
ا ÙØªÙ
استخداÙ
Ø¹ÙØ§Ù
Ù Ø§ÙØªØ´ØºÙÙ ÙØ°Ù Ø Ø¹ÙØ¯Ù
ا ÙØØªØ§Ø¬ Ø¥ÙÙ Ø§ÙØªÙاعب Ø¨Ø§ÙØ£Ø±ÙاÙ
عÙ٠أدÙÙ Ù
ستÙÙ (Ø£ØØ§Ø¯Ù Ø§ÙØ¨ØªØ§Øª). ÙÙ ÙØØªØ§Ø¬ Ø¥ÙÙ ÙØ¤Ùاء اÙÙ
شغÙÙÙ Ù٠أ٠ÙÙØª ÙØ±Ùب Ø ÙØ£Ù تطÙÙØ± اÙÙÙØ¨ ÙØ§ ÙØ³ØªØ®Ø¯Ù
ÙÙ
ÙØ«ÙØ±ÙØ§ Ø ÙÙÙÙ Ù٠بعض اÙÙ
Ø¬Ø§ÙØ§Øª Ø§ÙØ®Ø§ØµØ© Ø Ù
Ø«Ù Ø§ÙØªØ´ÙÙØ± Ø ÙÙÙ Ù
ÙÙØ¯Ø©. ÙÙ
ÙÙÙ ÙØ±Ø§Ø¡Ø© Ù
ÙØ§ÙØ© [Ø¹ÙØ§Ù
٠تشغÙÙ Bitwise] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise) Ù
ÙØ§ÙØ© ØÙÙ MDN Ø¹ÙØ¯ Ø§ÙØØ§Ø¬Ø©.
+=======
+These operators are used very rarely, when we need to fiddle with numbers on the very lowest (bitwise) level. We won't need these operators any time soon, as web development has little use of them, but in some special areas, such as cryptography, they are useful. You can read the [Bitwise Operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise_operators) chapter on MDN when a need arises.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## اÙÙØ§ØµÙØ©
diff --git a/1-js/02-first-steps/09-comparison/article.md b/1-js/02-first-steps/09-comparison/article.md
index 3dba72cc5..3cc0b1edf 100644
--- a/1-js/02-first-steps/09-comparison/article.md
+++ b/1-js/02-first-steps/09-comparison/article.md
@@ -4,10 +4,17 @@
: ÙÙÙ ÙØºØ© Ø§ÙØ¬Ø§ÙØ³ÙØ±Ùبت ØªÙØªØ¨ ÙÙ
ا ÙÙÙ
+<<<<<<< HEAD
- Ø£ÙØ¨Ø±/أصغر Ù
Ù: a > b, a < b.
- Ø£ÙØ¨Ø±/أصغر Ù
Ù Ø§Ù ÙØ³Ø§ÙÙ: a >= b, a <= b.
- ÙØ³Ø§ÙÙ: `a == b` Ø ÙØ±Ø¬Ù Ù
ÙØ§ØØ¸Ø© Ø£Ù Ø¹ÙØ§Ù
Ø© اÙÙ
Ø³Ø§ÙØ§Ø© اÙÙ
Ø²Ø¯ÙØ¬Ø©` = `تعÙ٠اختبار اÙÙ
Ø³Ø§ÙØ§Ø© Ø ÙÙ ØÙ٠أ٠ÙÙÙ
Ø© ÙØ§ØØ¯Ø©` a = b` تعÙ٠تعÙÙ٠أ٠Ù
Ø³Ø§ÙØ§Ø© .
- ÙØ§ تساÙÙ. ÙÙ Ø§ÙØ±ÙØ§Ø¶ÙØ§Øª ÙÙÙÙ Ø§ÙØªØ±Ù
ÙØ² ≠ ØÙÙÙ ÙÙ JavaScript ØªÙØªØ¨ ÙÙØ°Ø§ a != b.
+=======
+- Greater/less than: a > b, a < b.
+- Greater/less than or equals: a >= b, a <= b.
+- Equals: `a == b`, please note the double equality sign `==` means the equality test, while a single one `a = b` means an assignment.
+- Not equals: In maths the notation is ≠, but in JavaScript it's written as a != b.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ ÙØ°Ù اÙÙ
ÙØ§ÙØ© Ø³ÙØªØ¹ÙÙ
اÙÙ
Ø²ÙØ¯ Ø¹Ù Ø§ÙØ£ÙÙØ§Ø¹ اÙÙ
ختÙÙØ© Ù
٠اÙÙ
ÙØ§Ø±Ùات Ø ÙÙÙ٠تجعÙÙØ§ JavaScriptØ Ø¨Ù
ا Ù٠ذÙÙ Ø§ÙØ®ØµØ§Ø¦Øµ اÙÙ
ÙÙ
Ø©.
@@ -210,8 +217,16 @@ alert( undefined == 0 ); // false (3)
## Ù
ÙØ®Øµ
+<<<<<<< HEAD
- ترجع Ø¹ÙØ§Ù
٠اÙÙ
ÙØ§Ø±ÙØ© ÙÙÙ
Ø© Ù
ÙØ·ÙÙØ©.
- تتÙ
Ù
ÙØ§Ø±ÙØ© Ø§ÙØ³ÙØ§Ø³Ù ØØ±ÙÙØ§ Ø¨ØØ±Ù ÙÙ ØªØ±ØªÙØ¨ "اÙÙØ§Ù
ÙØ³".
- Ø¹ÙØ¯ Ù
ÙØ§Ø±ÙØ© اÙÙÙÙ
Ù
٠أÙÙØ§Ø¹ Ù
ختÙÙØ© Ø ÙØªÙ
تØÙÙÙÙØ§ Ø¥ÙÙ Ø£Ø±ÙØ§Ù
(Ø¨Ø§Ø³ØªØ«ÙØ§Ø¡ Ø§ÙØªØÙÙ Ù
٠اÙÙ
Ø³Ø§ÙØ§Ø© Ø§ÙØµØ§Ø±Ù
).
- اÙÙÙÙ
تا٠"null" Ù "undefined" تساÙÙ `==` Ø¨Ø¹Ø¶ÙØ§ Ø§ÙØ¨Ø¹Ø¶ ÙÙØ§ تساÙ٠أ٠ÙÙÙ
Ø© أخرÙ.
- ÙÙ ØØ°Ø±Ùا Ø¹ÙØ¯ استخداÙ
Ù
ÙØ§Ø±Ùات Ù
ث٠`>` Ø£Ù `<` Ù
ع اÙÙ
ØªØºÙØ±Ø§Øª Ø§ÙØªÙ ÙÙ
Ù٠أ٠تÙÙ٠أØÙاÙÙØ§ `خاÙÙØ© / ØºÙØ± Ù
ØØ¯Ø¯Ø© '. ÙÙØ¹Ø¯ Ø§ÙØªØÙÙ Ù
Ù "null / undefined" بشÙÙ Ù
ÙÙØµÙ ÙÙØ±Ø© Ø¬ÙØ¯Ø©.
+=======
+- Comparison operators return a boolean value.
+- Strings are compared letter-by-letter in the "dictionary" order.
+- When values of different types are compared, they get converted to numbers (with the exclusion of a strict equality check).
+- The values `null` and `undefined` are equal `==` to themselves and each other, but do not equal any other value.
+- Be careful when using comparisons like `>` or `<` with variables that can occasionally be `null/undefined`. Checking for `null/undefined` separately is a good idea.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/02-first-steps/10-ifelse/article.md b/1-js/02-first-steps/10-ifelse/article.md
index b733a4e7a..3b6256106 100644
--- a/1-js/02-first-steps/10-ifelse/article.md
+++ b/1-js/02-first-steps/10-ifelse/article.md
@@ -68,9 +68,13 @@ if (cond) {
## عبارة "else"
+<<<<<<< HEAD
عبارة `if` ÙØ¯ ØªØØªÙ٠عÙ٠جزء "else" Ø¥Ø®ØªÙØ§Ø±Ù. ÙØªÙ
تÙÙÙØ°Ùا Ø¹ÙØ¯Ù
ا ÙÙÙÙ Ø§ÙØ´Ø±Ø· false.
عÙ٠سبÙ٠اÙÙ
ثاÙ:
+=======
+The `if` statement may contain an optional `else` block. It executes when the condition is falsy.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let year = prompt("Ù٠أ٠عاÙ
تÙ
ÙØ´Ø± ØªØ®ØµÙØµØ§Øª ECMAScript-2015?", "");
@@ -187,10 +191,17 @@ alert(message);
ربÙ
ا ÙÙÙÙ Ù
Ù Ø§ÙØµØ¹Ø¨ Ù
Ø¹Ø±ÙØ© Ù
ا ÙØØ¯Ø« ÙÙÙ٠إذا ÙØ¸Ø±Ùا Ø¹Ù ÙØ±Ø¨ Ø³ÙØ¬Ø¯ Ø£ÙÙ Ù
جرد تتابع ÙÙ
جÙ
ÙØ¹Ø© إختبارات:
+<<<<<<< HEAD
1. Ø£ÙÙ Ø¹ÙØ§Ù
Ø© استÙÙØ§Ù
تختبر إذا ÙØ§Ù `age < 3`.
2. Ù٠صØÙØ ØªØ±Ø¬Ø¹ `'Ù
Ø±ØØ¨Ùا ÙØ§ ØµØºÙØ±Ù!'`. ÙÙÙ ÙÙ
ÙÙ٠تÙÙ
Ù ÙÙ
ا بعد اÙÙÙØ·ØªÙÙ '":"'ÙØªØ®ØªØ¨Ø± `age < 18`.
3. Ù٠صØÙØ ØªØ±Ø¬Ø¹ `'Ø£ÙÙØ§!'`. ÙÙÙ ÙÙ
ÙÙ٠تÙÙ
Ù ÙÙ
ا بعد اÙÙÙØ·ØªÙÙ '":"'ÙØªØ®ØªØ¨Ø± `age < 100`.
4. Ù٠صØÙØ ØªØ±Ø¬Ø¹ `'تØÙاتÙ!'`. ÙÙÙ ÙÙ
ÙÙ٠تÙÙ
Ù ÙÙ
ا بعد اÙÙÙØ·ØªÙÙ Ø§ÙØ£Ø®ÙرتÙÙ '":"'ÙØªØ±Ø¬Ø¹ `'ÙØ§ ÙÙ Ù
٠عÙ
ر ØºÙØ± عادÙ!'`.
+=======
+1. The first question mark checks whether `age < 3`.
+2. If true -- it returns `'Hi, baby!'`. Otherwise, it continues to the expression after the colon ":", checking `age < 18`.
+3. If that's true -- it returns `'Hello!'`. Otherwise, it continues to the expression after the next colon ":", checking `age < 100`.
+4. If that's true -- it returns `'Greetings!'`. Otherwise, it continues to the expression after the last colon ":", returning `'What an unusual age!'`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ§ Ù
ا ÙØ¨Ø¯Ù عÙÙ٠باستخداÙ
`if..else`:
diff --git a/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md b/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md
index 1983d4b2f..7fef5add7 100644
--- a/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md
+++ b/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md
@@ -1,6 +1,6 @@
Ø§ÙØ¥Ø¬Ø§Ø¨Ø©: `null` ÙØ£ÙÙØ§ Ø£ÙÙ ÙÙÙ
Ø© falsy Ù٠اÙÙØ§Ø¦Ù
Ø©.
```js run
-alert( 1 && null && 2 );
+alert(1 && null && 2);
```
diff --git a/1-js/02-first-steps/11-logical-operators/article.md b/1-js/02-first-steps/11-logical-operators/article.md
index 422fd59da..1ccdf21f7 100644
--- a/1-js/02-first-steps/11-logical-operators/article.md
+++ b/1-js/02-first-steps/11-logical-operators/article.md
@@ -124,7 +124,11 @@ alert(undefined || null || 0); // 0 (اÙÙÙ falsy, ترجع آخر ÙÙÙ
Ø©)
ÙÙØ¹Ù٠أ٠`||` ÙÙÙØ° Ø§ÙØ¹Ù
ÙÙØ§Øª اÙÙ
Ù
ررة ÙÙ ØØªÙ Ø£ÙÙ ÙÙÙ
Ø© truthy ÙØ¨Ø¹Ø¯ ذÙÙ ÙØªÙ
إرجاع اÙÙÙÙ
Ø© Ù
باشرة بدÙÙ ÙÙ
س باÙÙ Ø§ÙØ¹Ù
ÙÙØ§Øª.
+<<<<<<< HEAD
Ø£ÙÙ
ÙØ© ÙØ°Ù اÙÙ
ÙØ²Ø© ØªØµØ¨Ø Ù
ÙØÙØ¸Ø© إذا ÙØ§Ùت اÙÙÙÙ
Ø© اÙÙ
Ù
ررة عبارة ع٠عÙ
ÙÙØ© ÙÙØ§ آثار Ø¬Ø§ÙØ¨ÙØ© Ù
Ø«Ù ØªØ®ØµÙØµ ÙÙÙ
Ø© Ù
ØªØºÙØ± أ٠استدعاء Ø¯Ø§ÙØ©
+=======
+ The importance of this feature becomes obvious if an operand isn't just a value, but an expression with a side effect, such as a variable assignment or a function call.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ ÙØ°Ø§ اÙÙ
Ø«Ø§Ù Ø³ÙØªÙ
طباعة Ø§ÙØ±Ø³Ø§ÙØ© Ø§ÙØ£ÙÙÙ ÙÙÙ ÙØªÙ
طباعة Ø§ÙØ«Ø§ÙÙØ©:
diff --git a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
index 49aa38cb4..cf75300b6 100644
--- a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
+++ b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
@@ -4,7 +4,11 @@
ÙØªÙ
ÙØªØ§Ø¨Ø© عاÙ
Ù Ø§ÙØªØÙÙ Ù
٠اÙÙØ±Ø§Øº ÙØ¹ÙاÙ
ت٠استÙÙØ§Ù
`??`.
+<<<<<<< HEAD
ÙØ¸Ø±Ùا ÙØ£ÙÙ ÙØ¹Ø§Ù
Ù `null` Ù `undefined` بطرÙÙØ© Ù
Ù
Ø§Ø«ÙØ© Ø Ø³ÙØ³ØªØ®Ø¯Ù
Ù
ØµØ·ÙØÙØ§ Ø®Ø§ØµÙØ§ ÙÙØ§ Ø ÙÙ ÙØ°Ù اÙÙ
ÙØ§ÙØ©. سÙÙÙÙ Ø£Ù Ø§ÙØªØ¹Ø¨Ùر "Ù
ØØ¯Ø¯" Ø¹ÙØ¯Ù
ا ÙØ§ ÙÙÙÙ `null` ÙÙØ§ `undefined`.
+=======
+As it treats `null` and `undefined` similarly, we'll use a special term here, in this article. For brevity, we'll say that a value is "defined" when it's neither `null` nor `undefined`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØªÙجة `a ?? b` ÙÙ:
- إذا ÙØ§Ù `a` Ù
ØØ¯Ø¯Ùا Ø ÙØ¥Ù `a`Ø
@@ -22,14 +26,24 @@ result = (a !== null && a !== undefined) ? a : b;
Ø§ÙØ¢Ù ÙØ¬Ø¨ Ø£Ù ÙÙÙÙ Ù
٠اÙÙØ§Ø¶Ø تÙ
اÙ
ÙØ§ Ù
ا ÙÙØ¹ÙÙ `??`. Ø¯Ø¹ÙØ§ ÙØ±Ù Ø£ÙÙ ÙØ³Ø§Ø¹Ø¯.
+<<<<<<< HEAD
ØØ§ÙØ© Ø§ÙØ§Ø³ØªØ®Ø¯Ø§Ù
Ø§ÙØ´Ø§Ø¦Ø¹Ø© ÙÙ `??` Ù٠تÙÙÙØ± ÙÙÙ
Ø© Ø§ÙØªØ±Ø§Ø¶ÙØ© ÙÙ
ØªØºÙØ± Ù
ØØªÙ
٠أ٠ÙÙÙÙ ØºÙØ± Ù
ØØ¯Ø¯.
عÙ٠سبÙ٠اÙÙ
Ø«Ø§Ù Ø ÙÙØ§ ÙØ¹Ø±Ø¶ `user` إذا تÙ
ØªØØ¯ÙØ¯Ù Ø ÙØ¥Ùا `Anonymous`:
+=======
+The common use case for `??` is to provide a default value.
+
+For example, here we show `user` if its value isn't `null/undefined`, otherwise `Anonymous`:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let user;
+<<<<<<< HEAD
alert(user ?? "Ù
جÙÙ٠اÙÙÙÙØ©"); // Ù
جÙÙ٠اÙÙÙÙØ© (ÙÙ
ÙØªÙ
ØªØØ¯Ùد اÙÙ
ستخدÙ
)
+=======
+alert(user ?? "Anonymous"); // Anonymous (user is undefined)
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
ÙØ°Ø§ Ù
ثا٠عÙÙ `user` اÙÙ
عÙÙ ÙØ§Ø³Ù
:
@@ -37,14 +51,24 @@ alert(user ?? "Ù
جÙÙ٠اÙÙÙÙØ©"); // Ù
جÙÙ٠اÙÙÙÙØ© (ÙÙ
ÙØª
```js run
let user = "John";
+<<<<<<< HEAD
alert(user ?? "Ù
جÙÙ٠اÙÙÙÙØ©"); // John (تÙ
ØªØØ¯Ùد اÙÙ
ستخدÙ
)
+=======
+alert(user ?? "Anonymous"); // John (user is not null/undefined)
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
ÙÙ
ÙÙÙØ§ Ø£ÙØ¶Ùا استخداÙ
ØªØ³ÙØ³Ù `??` ÙØªØØ¯Ùد اÙÙÙÙ
Ø© Ø§ÙØ£ÙÙÙ Ù
Ù ÙØ§Ø¦Ù
Ø© ÙÙØ³Øª `null/undefined`.
+<<<<<<< HEAD
ÙÙÙØªØ±Ø¶ Ø£Ù ÙØ¯ÙÙØ§ Ø¨ÙØ§Ùات اÙÙ
ستخدÙ
Ù٠اÙÙ
ØªØºÙØ±Ø§Øª `firstName` Ù `lastName` Ø£Ù `nickName`. ÙØ¯ ÙØ§ ÙØªÙ
ØªØØ¯Ùد ÙÙ Ù
ÙÙÙ
ا Ø Ø¥Ø°Ø§ ÙØ±Ø± اÙÙ
ستخدÙ
عدÙ
إدخا٠ÙÙÙ
Ø©.
ÙÙØ¯ عرض اسÙ
اÙÙ
ستخدÙ
باستخداÙ
Ø£ØØ¯ ÙØ°Ù اÙÙ
ØªØºÙØ±Ø§Øª Ø Ø£Ù Ø¹Ø±Ø¶ "Ù
جÙÙ٠اÙÙÙÙØ©" إذا ÙÙ
ÙØªÙ
ØªØØ¯Ùد ÙÙ Ù
ÙÙÙ
.
+=======
+Let's say we have a user's data in variables `firstName`, `lastName` or `nickName`. All of them may be not defined, if the user decided not to fill in the corresponding values.
+
+We'd like to display the user name using one of these variables, or show "Anonymous" if all of them are `null/undefined`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ³ØªØ®Ø¯Ù
عاÙ
Ù Ø§ÙØªØÙÙ Ù
٠اÙÙØ±Ø§Øº `??` ÙØ°ÙÙ:
@@ -78,7 +102,11 @@ alert(firstName || lastName || nickName || "Ù
جÙÙ٠اÙÙÙÙØ©"); // Superc
*/!*
```
+<<<<<<< HEAD
ØªØ§Ø±ÙØ®ÙÙØ§ Ø ÙØ§Ù عاÙ
Ù OR `||` ÙÙØ§Ù Ø£ÙÙØ§Ù. ÙÙØ¯ ÙØ§Ù Ù
ÙØ¬ÙØ¯ÙØ§ Ù
ÙØ° Ø¨Ø¯Ø§ÙØ© JavaScript Ø ÙØ°ÙÙ ÙØ§Ù اÙÙ
Ø·ÙØ±ÙÙ ÙØ³ØªØ®Ø¯Ù
ÙÙÙ ÙÙ
Ø«Ù ÙØ°Ù Ø§ÙØ£ØºØ±Ø§Ø¶ ÙÙØªØ±Ø© Ø·ÙÙÙØ©.
+=======
+Historically, the OR `||` operator was there first. It's been there since the beginning of JavaScript, so developers were using it for such purposes for a long time.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù
Ù ÙØ§ØÙØ© Ø£Ø®Ø±Ù Ø ØªÙ
ت Ø¥Ø¶Ø§ÙØ© عاÙ
Ù Ø§ÙØªØÙÙ Ù
٠اÙÙØ±Ø§Øº `??` Ø¥ÙÙ JavaScript Ù
Ø¤Ø®Ø±ÙØ§ ÙÙØ· Ø ÙÙØ§Ù Ø§ÙØ³Ø¨Ø¨ Ù٠ذÙ٠أ٠اÙÙØ§Ø³ ÙÙ
ÙÙÙÙÙØ§ راضÙ٠تÙ
اÙ
ÙØ§ ع٠`||`.
@@ -108,11 +136,19 @@ alert(height ?? 100); // 0
## Ø§ÙØ£ÙÙÙÙØ©
+<<<<<<< HEAD
تعاد٠أÙÙÙÙØ© عاÙ
Ù Ø§ÙØªØÙÙ Ù
٠اÙÙØ±Ø§Øº `??` ØªÙØ±ÙØ¨ÙØ§ ÙÙØ³ `||` Ø ÙÙØ· ÙÙÙÙÙØ§ أدÙÙ. ÙØ³Ø§ÙÙ `5` ÙÙ [جدÙÙ MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table) Ø Ø¨ÙÙÙ
ا `||` ÙÙ `6`.
+=======
+The precedence of the `??` operator is the same as `||`. They both equal `3` in the [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ°Ø§ ÙØ¹Ù٠أÙÙ Ù
ث٠`||` Ø ÙØªÙ
تÙÙÙÙ
عاÙ
Ù Ø§ÙØªØÙÙ Ù
٠اÙÙØ±Ø§Øº `??` ÙØ¨Ù `=` Ù `Ø` Ø ÙÙÙ٠بعد Ù
عظÙ
Ø§ÙØ¹Ù
ÙÙØ§Øª Ø§ÙØ£Ø®Ø±Ù Ù
ث٠`+` ٠`*`.
+<<<<<<< HEAD
ÙØ°Ù٠إذا ÙÙØ§ ÙØ±ØºØ¨ ÙÙ Ø§Ø®ØªÙØ§Ø± ÙÙÙ
Ø© Ù
ع `??` ÙÙ ØªØ¹Ø¨ÙØ± Ù
ع Ø¹ÙØ§Ù
Ù Ø£Ø®Ø±Ù Ø ÙÙØ± ÙÙ Ø¥Ø¶Ø§ÙØ© Ø£ÙÙØ§Ø³:
+=======
+So we may need to add parentheses in expressions like this:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let height = null;
@@ -130,7 +166,11 @@ alert(area); // 5000
// بدÙ٠أÙÙØ§Ø³
let area = height ?? 100 * width ?? 50;
+<<<<<<< HEAD
// ... ÙØ¹Ù
٠بÙÙØ³ Ø§ÙØ·Ø±ÙÙØ© ÙÙØ°Ø§ (ربÙ
ا ÙÙØ³ Ù
ا ÙØ±ÙدÙ):
+=======
+// ...works this way (not what we want):
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
let area = height ?? (100 * width) ?? 50;
```
diff --git a/1-js/02-first-steps/13-while-for/article.md b/1-js/02-first-steps/13-while-for/article.md
index 3dd3a9db0..3c19078c7 100644
--- a/1-js/02-first-steps/13-while-for/article.md
+++ b/1-js/02-first-steps/13-while-for/article.md
@@ -6,7 +6,24 @@
_Ø§ÙØÙÙØ§Øª Ø§ÙØªÙØ±Ø§Ø±ÙØ©_ Ù٠طرÙÙØ© ÙØªÙرار Ø§ÙØ£ÙاÙ
ر.
+<<<<<<< HEAD
## ØÙÙØ© "while"
+=======
+```smart header="The for..of and for..in loops"
+A small announcement for advanced readers.
+
+This article covers only basic loops: `while`, `do..while` and `for(..;..;..)`.
+
+If you came to this article searching for other types of loops, here are the pointers:
+
+- See [for..in](info:object#forin) to loop over object properties.
+- See [for..of](info:array#loops) and [iterables](info:iterable) for looping over arrays and iterable objects.
+
+Otherwise, please read on.
+```
+
+## The "while" loop
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¥Ù ØÙÙØ© `while` ØªÙØªØ¨ Ø¨Ø§ÙØ·Ø±ÙÙØ© Ø§ÙØªØ§ÙÙØ©:
@@ -106,12 +123,21 @@ for (let i = 0; i < 3; i++) {
ÙÙØ´Ø±Ø `for` جزء بجزء:
+<<<<<<< HEAD
| Ø§ÙØ¬Ø²Ø¡ | | |
| --------- | ---------- | ----------------------------------------------------------- |
| begin | `i = 0` | ÙÙÙØ° Ù
رة ÙØ§ØØ¯Ø© ÙÙØ· ÙÙ Ø§ÙØ¨Ø¯Ø§ÙØ©. |
| condition | `i < 3` | ÙØªÙ
Ø§Ø®ØªØ¨Ø§Ø±Ù ÙØ¨Ù Ù٠عÙ
ÙÙØ© ØªÙØ±Ø§Ø± ÙØ¥Ø°Ø§ ÙÙ
ÙØªØÙÙ ÙØªÙÙÙ Ø§ÙØªÙرار. |
| body | `alert(i)` | تÙÙØ° طاÙÙ
ا Ø§ÙØ´Ø±Ø· Ù
ØÙÙ. |
| step | `i++` | ÙÙÙØ° بعد body ÙÙ Ù٠عÙ
ÙÙØ© ØªÙØ±Ø§Ø±. |
+=======
+| part | | |
+|-------|----------|----------------------------------------------------------------------------|
+| begin | `let i = 0` | Executes once upon entering the loop. |
+| condition | `i < 3`| Checked before every loop iteration. If false, the loop stops. |
+| body | `alert(i)`| Runs again and again while the condition is truthy. |
+| step| `i++` | Executes after the body on each iteration. |
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø§ÙØ®ÙارزÙ
ÙØ© Ø§ÙØ¹Ø§Ù
Ø© ÙÙØªÙرار تعÙ
Ù ÙØ§ÙتاÙÙ:
@@ -173,12 +199,15 @@ for (i = 0; i < 3; i++) { // استخداÙ
Ù
ØªØºÙØ± Ù
عر٠Ù
سبÙÙØ§
alert(i); // 3, ÙÙ
ÙÙ Ø§ÙØªØ¹Ø§Ù
Ù Ù
Ø¹Ù ÙØ£ÙÙ Ù
عر٠خارج Ø§ÙØÙÙØ©
```
-
````
+<<<<<<< HEAD
### أجزاء ÙÙ
Ù٠تخطÙÙØ§
أ٠جزء Ù
Ù `for` ÙÙ
ÙÙ Ø§ÙØ§Ø³ØªØºÙاء عÙÙ.
+=======
+### Skipping parts
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù
Ø«ÙÙØ§ إذا ØØ°ÙÙØ§ `begin` ÙÙ ÙÙÙÙ ÙØ¯ÙÙØ§ Ù
ا ÙÙØ¹ÙÙ ÙÙ Ø¨Ø¯Ø§ÙØ© Ø§ÙØÙÙØ©.
@@ -277,7 +306,12 @@ for (let i = 0; i < 10; i++) {
ÙØ°Ø§ اÙÙÙØ¯ Ù
طاب٠تÙ
اÙ
ÙØ§ ÙÙØ³Ø§Ø¨Ù. ÙÙ
ÙÙÙØ§ ÙÙØ· ÙØ¶Ø¹ اÙÙÙØ¯ داخ٠`if` بدÙÙØ§ Ù
٠استخداÙ
`continue`.
+<<<<<<< HEAD
ÙÙÙÙ ÙØ°Ø§ ÙÙØªØ¬ Ù
ستÙ٠آخر Ù
Ù Ø§ÙØªØ¯Ø§Ø®Ù (استدعاء `alert` داخ٠أÙÙØ§Ø³ Ù
عÙÙÙØ©). إذا ÙØ§Ù Ù
ا بداخ٠`if` Ø³Ø·ÙØ± ÙØ«Ùرة ÙÙØ°Ø§ سÙÙÙÙ Ù
٠إÙ
ÙØ§ÙÙØ© ÙØ±Ø§Ø¡Ø© اÙÙÙØ¯ Ø¨ÙØ¶ÙØ.
+=======
+But as a side effect, this created one more level of nesting (the `alert` call inside the curly braces). If the code inside of `if` is longer than a few lines, that may decrease the overall readability.
+````
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
`````
@@ -296,7 +330,6 @@ if (i > 5) {
...ÙÙØªØ¨Ùا٠باستخداÙ
Ø¹ÙØ§Ù
Ø© Ø§ÙØ§Ø³ØªÙÙØ§Ù
:
-
```js no-beautify
(i > 5) ? alert(i) : *!*continue*/!*; // continue ÙØ§ ÙØ³Ù
Ø Ø¨Ø§Ø³ØªØ®Ø¯Ø§Ù
ÙØ§ ÙÙØ§
```
@@ -330,6 +363,11 @@ alert("Done!");
Ø¥Ù _label_ ÙÙÙÙ
بتعرÙÙ Ø§ÙØÙÙØ© باستخداÙ
ÙÙØ·ØªÙÙ ÙØ¨ÙÙØ§:
+<<<<<<< HEAD
+=======
+A *label* is an identifier with a colon before a loop:
+
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
labelName: for (...) {
...
@@ -351,6 +389,7 @@ labelName: for (...) {
// Ø£ÙØ¹Ù شئ Ù
ا باÙÙÙÙ
Ø©...
}
}
+
alert('Done!');
```
@@ -370,16 +409,37 @@ for (let i = 0; i < 3; i++) { ... }
````warn header="Labels ÙØ§ تستخدÙ
ÙÙØ¥ÙØªÙØ§Ù Ø¥Ù٠أ٠Ù
ÙØ§Ù"
Labels ÙØ§ تسÙ
Ø ÙÙØ§ Ø¨Ø§ÙØ¥ÙØªÙØ§Ù Ø¥Ù٠أ٠Ù
ÙØ§Ù داخ٠اÙÙÙØ¯.
+<<<<<<< HEAD
ÙØ¹Ù٠سبÙ٠اÙÙ
Ø«Ø§Ù ÙØ§ ÙÙ
ÙÙÙØ§ ÙØ¹Ù Ø§ÙØªØ§ÙÙ:
+=======
+For example, it is impossible to do this:
+
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
break label; // ØªÙØªÙ٠إÙÙ Ø§ÙØÙÙ Ø¨Ø§ÙØ£Ø³ÙÙ (ÙØ§ تعÙ
Ù)
label: for (...)
```
+<<<<<<< HEAD
إستخداÙ
`continue` ÙÙÙÙ Ù
Ù
ÙÙÙØ§ ÙÙØ· Ù
Ù Ø¯Ø§Ø®Ù Ø§ÙØÙÙÙ.
`break` ربÙ
ا ÙÙ
ÙÙ ÙØ¶Ø¹Ù ÙØ¨Ù Ø§ÙØ´ÙÙØ±Ø© Ø§ÙØ¶Ùا, as `label: { ... }`, ÙÙÙÙØ§ ÙØ§ تستخدÙ
Ø£Ø¨Ø¯ÙØ§ Ø¨ÙØ°Ù Ø§ÙØ·Ø±ÙÙØ©. ÙÙ٠تعÙ
Ù Ø£ÙØ¶Ùا Ù
Ù Ø§ÙØ¯Ø§Ø®Ù Ø¥ÙÙ Ø§ÙØ®Ø§Ø±Ø¬ ÙÙØ·.
+=======
+A `break` directive must be inside a code block. Technically, any labelled code block will do, e.g.:
+
+```js
+label: {
+ // ...
+ break label; // works
+ // ...
+}
+```
+
+...Although, 99.9% of the time `break` is used inside loops, as we've seen in the examples above.
+
+A `continue` is only possible from inside a loop.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
````
## Ù
ÙØ®Øµ
diff --git a/1-js/02-first-steps/14-switch/article.md b/1-js/02-first-steps/14-switch/article.md
index 1d63ee61d..e71780b91 100644
--- a/1-js/02-first-steps/14-switch/article.md
+++ b/1-js/02-first-steps/14-switch/article.md
@@ -139,7 +139,11 @@ switch (a) {
Ø§ÙØ¢Ù ÙÙ Ù
Ù `3` Ù `5` ÙØ¸ÙرÙÙ Ø§ÙØ±Ø³Ø§ÙØ©.
+<<<<<<< HEAD
Ø¥Ù
ÙØ§ÙÙØ© تجÙ
ÙØ¹ Ø§ÙØØ§ÙØ§Øª ÙÙ ØªØ£Ø«ÙØ± Ø¬Ø§ÙØ¨Ù ÙØ·Ø±ÙÙØ© عÙ
Ù `switch/case` بدÙÙ `break`. ÙÙØ§ ÙØ¨Ø¯Ø£ Ø§ÙØªÙÙÙØ° Ù
Ù `case 3` ÙÙ Ø§ÙØ³Ø·Ø± `(*)` ÙÙÙØªÙ٠إÙÙ `case 5` ÙØ¹Ø¯Ù
ÙØ¬Ùد `break`.
+=======
+The ability to "group" cases is a side effect of how `switch/case` works without `break`. Here the execution of `case 3` starts from the line `(*)` and goes through `case 5`, because there's no `break`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## Ø§ÙØ£ÙÙØ§Ø¹ Ù
ÙÙ
Ø©
diff --git a/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md b/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md
index 033be1578..75e97e532 100644
--- a/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md
+++ b/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md
@@ -1 +1,7 @@
-ÙØ§ Ø§Ø®ØªÙØ§Ù.
\ No newline at end of file
+<<<<<<< HEAD
+ÙØ§ Ø§Ø®ØªÙØ§Ù.
+=======
+No difference!
+
+In both cases, `return confirm('Did parents allow you?')` executes exactly when the `if` condition is falsy.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md b/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md
index 191d03c97..17656a48d 100644
--- a/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md
+++ b/1-js/02-first-steps/15-function-basics/2-rewrite-function-question-or/solution.md
@@ -14,4 +14,8 @@ function checkAge(age) {
}
```
+<<<<<<< HEAD
ÙØ§ØØ¸ Ø£Ù Ø§ÙØ£ÙÙØ§Ø³ ØÙÙ `age > 18` ØºÙØ± Ù
Ø·ÙÙØ¨Ø© ÙÙÙ٠تÙ
ÙØ¶Ø¹Ùا ÙØ²Ùادة اÙÙØ¯Ø±Ø© عÙÙ ÙØ±Ø§Ø¡Ø© اÙÙÙØ¯.
+=======
+Note that the parentheses around `age > 18` are not required here. They exist for better readability.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/02-first-steps/15-function-basics/article.md b/1-js/02-first-steps/15-function-basics/article.md
index 0c7b690e3..01d797fbd 100644
--- a/1-js/02-first-steps/15-function-basics/article.md
+++ b/1-js/02-first-steps/15-function-basics/article.md
@@ -20,11 +20,15 @@ function showMessage() {
}
```
+<<<<<<< HEAD
ÙÙÙ
Ø© `function` ØªÙØªØ¨ Ø£ÙÙØ§ Ø«Ù
ÙÙØªØ¨ _اسÙ
Ø§ÙØ¯Ø§ÙØ©_ Ø«Ù
ÙØ§Ø¦Ù
Ø© _parameters_ بÙ٠اÙÙÙØ³ÙÙ (ÙÙØµÙ بÙÙÙÙ
Ø¨ÙØ§ØµÙØ© ÙÙÙ ÙØ§Ø±ØºØ© Ù٠اÙÙ
Ø«Ø§Ù Ø§ÙØ³Ø§Ø¨Ù) ÙØ£Ø®Ùرا اÙÙÙØ¯ Ø§ÙØ°Ù ÙÙÙØ° ÙÙØ³Ù
Ù "the function body" بÙ٠اÙÙÙØ³Ù٠اÙÙ
عÙÙÙÙÙ.
+=======
+The `function` keyword goes first, then goes the *name of the function*, then a list of *parameters* between the parentheses (comma-separated, empty in the example above, we'll see examples later) and finally the code of the function, also named "the function body", between curly braces.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
-function name(parameters) {
- ...body...
+function name(parameter1, parameter2, ... parameterN) {
+ // body
}
```
@@ -137,25 +141,30 @@ alert( userName ); // *!*John*/!*, ÙÙ
ÙØªØºÙر, Ø§ÙØ¯Ø§ÙØ© Ù٠تص٠Ù
## Parameters
+<<<<<<< HEAD
ÙÙ
ÙÙÙØ§ تÙ
Ø±ÙØ± Ø£Ù ÙÙÙ
Ø¥ÙÙ Ø§ÙØ¯Ø§ÙØ© باستخداÙ
parameters (Ø£ÙØ¶Ùا تسÙ
Ù _function arguments_) .
+=======
+We can pass arbitrary data to functions using parameters.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ ÙØ°Ø§ اÙÙ
Ø«Ø§Ù Ø§ÙØ¯Ø§ÙØ© ÙØ¯ÙÙØ§ Ù
عاÙ
ÙÙÙ: `from` Ù `text`.
```js run
-function showMessage(*!*from, text*/!*) { // arguments: from, text
+function showMessage(*!*from, text*/!*) { // parameters: from, text
alert(from + ': ' + text);
}
-*!*
-showMessage('Ann', 'Hello!'); // Ann: Hello! (*)
-showMessage('Ann', "What's up?"); // Ann: What's up? (**)
-*/!*
+*!*showMessage('Ann', 'Hello!');*/!* // Ann: Hello! (*)
+*!*showMessage('Ann', "What's up?");*/!* // Ann: What's up? (**)
```
Ø¹ÙØ¯ استدعاء Ø§ÙØ¯Ø§ÙØ© ÙÙ Ø§ÙØ³Ø·Ø± `(*)` Ù `(**)` ÙØ¥Ù اÙÙÙÙ
اÙÙ
Ù
ررة ØªÙØ³Ø® Ø¥Ù٠اÙÙ
ØªØºÙØ±Ø§Øª اÙÙ
ØÙÙØ© `from` Ù `text`. Ø«Ù
تÙÙÙ
Ø§ÙØ¯Ø§ÙØ© باستخداÙ
ÙÙ
.
+<<<<<<< HEAD
ÙÙØ§ Ù
ثا٠آخر ØÙØ« ÙØ¯ÙÙØ§ اÙÙ
ØªØºÙØ± `from` ÙÙÙ
ÙØ§ بتÙ
Ø±ÙØ±Ù Ø¥ÙÙ Ø§ÙØ¯Ø§ÙØ©. ÙØ§ØØ¸ Ø£Ù Ø§ÙØ¯Ø§ÙØ© ÙØ§Ù
ت بتغÙÙØ± ÙÙÙ
Ø© `from` ÙÙÙÙ Ø§ÙØªØºÙÙØ± ÙØ§ ÙØ¤Ø«Ø± Ù٠اÙÙ
ØªØºÙØ± اÙÙ
Ù
رر ÙØ£Ù Ø§ÙØ¯Ø§ÙØ© ØªØØµÙ عÙÙ ÙØ³Ø®Ø© Ù
٠اÙÙÙÙ
Ø©:
+=======
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
function showMessage(from, text) {
@@ -174,9 +183,27 @@ showMessage(from, "Hello"); // *Ann*: Hello
alert( from ); // Ann
```
+<<<<<<< HEAD
## اÙÙÙÙ
Ø§ÙØ¥ÙØªØ±Ø§Ø¶ÙØ©
إذا ÙÙ
ÙØªÙ
تÙ
Ø±ÙØ± ÙÙÙ
Ø© Parameter ÙØ£Ø®Ø° اÙÙÙÙ
Ø© `undefined`.
+=======
+When a value is passed as a function parameter, it's also called an *argument*.
+
+In other words, to put these terms straight:
+
+- A parameter is the variable listed inside the parentheses in the function declaration (it's a declaration time term).
+- An argument is the value that is passed to the function when it is called (it's a call time term).
+
+We declare functions listing their parameters, then call them passing arguments.
+
+In the example above, one might say: "the function `showMessage` is declared with two parameters, then called with two arguments: `from` and `"Hello"`".
+
+
+## Default values
+
+If a function is called, but an argument is not provided, then the corresponding value becomes `undefined`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
عÙ٠سبÙ٠اÙÙ
ثا٠اÙÙÙÙØ´Ù Ø§ÙØ³Ø§Ø¨ÙØ© `showMessage(from, text)` ÙÙ
ÙÙ Ø§Ø³ØªØ¯Ø¹Ø§Ø¦ÙØ§ ÙØªÙ
Ø±ÙØ± ÙÙÙ
Ø© ÙØ§ØØ¯Ø© ÙÙØ·:
@@ -184,9 +211,15 @@ alert( from ); // Ann
showMessage("Ann");
```
+<<<<<<< HEAD
ÙØ°Ø§ ÙÙØ³ خطأ ÙÙÙ٠سÙÙØªØ¬ `"Ann: undefined"`. ÙÙ
ÙØªÙ
تÙ
Ø±ÙØ± `text` ÙØ°ÙÙ ÙØªÙ
Ø§ÙØªØ±Ø§Ø¶ Ø£Ù `text === undefined`.
إذا أردت ØªØ®ØµÙØµ ÙÙÙ
Ø© Ø¥ÙØªØ±Ø§Ø¶ÙØ© Ù `text` ÙÙ
ÙÙ ÙØ¶Ø¹Ùا بعد `=`:
+=======
+That's not an error. Such a call would output `"*Ann*: undefined"`. As the value for `text` isn't passed, it becomes `undefined`.
+
+We can specify the so-called "default" (to use if omitted) value for a parameter in the function declaration, using `=`:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
function showMessage(from, *!*text = "no text given"*/!*) {
@@ -196,7 +229,17 @@ function showMessage(from, *!*text = "no text given"*/!*) {
showMessage("Ann"); // Ann: no text given
```
+<<<<<<< HEAD
إذا ÙÙ
ÙØªÙ
تÙ
Ø±ÙØ± ÙÙÙ
Ø© `text` Ø³ÙØªÙ
إعطائ٠اÙÙÙÙ
Ø© `"no text given"`
+=======
+Now if the `text` parameter is not passed, it will get the value `"no text given"`.
+
+The default value also jumps in if the parameter exists, but strictly equals `undefined`, like this:
+
+```js
+showMessage("Ann", undefined); // Ann: no text given
+```
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ§ استخدÙ
ÙØ§ اÙÙØµ `"no text given"` ÙÙÙÙ ÙÙ
Ù٠أ٠تÙÙ٠اÙÙÙÙ
Ø© Ù
Ø¹ÙØ¯Ø© Ø£ÙØ«Ø± Ù
Ù:
@@ -210,6 +253,7 @@ function showMessage(from, text = anotherFunction()) {
```smart header="تÙÙÙØ° اÙÙÙÙ
Ø§ÙØ¥ÙØªØ±Ø§Ø¶ÙØ©"
ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØªÙ
تÙÙÙØ° اÙÙÙÙ
Ø§ÙØ¥ÙØªØ±Ø§Ø¶ÙØ© ÙÙ ÙÙ Ù
رة ÙØªÙ
استدعاء Ø§ÙØ¯Ø§ÙØ© دÙ٠تÙ
Ø±ÙØ± ÙÙÙ
Ø©.
+<<<<<<< HEAD
Ù٠اÙÙ
Ø«Ø§Ù Ø§ÙØ³Ø§Ø¨Ù Ø³ÙØªÙ
تÙÙÙØ° `anotherFunction()` ÙÙ ÙÙ Ù
رة ÙØªÙ
استدعا `showMessage()` دÙ٠تÙ
Ø±ÙØ± ÙÙÙ
Ø© `text`.
```
@@ -218,11 +262,57 @@ function showMessage(from, text = anotherFunction()) {
Ø£ØÙØ§ÙØ§ ÙØ±ÙØ¯ØªØØ¯Ùد ÙÙÙ
Ø© ÙØ¥ÙØªØ±Ø§Ø¶ÙØ© ÙÙÙÙ ÙÙØ³ Ù٠تعرÙÙ Ø§ÙØ¯Ø§ÙØ© ب٠ÙÙ ÙÙØª ÙØ§ØÙ Ø£Ø«ÙØ§Ø¡ Ø§ÙØªÙÙÙØ°.
ÙÙ
Ø¹Ø±ÙØ© اÙÙ
ØªØºÙØ± Ø§ÙØ°Ù ÙÙ
ÙÙ
رر ÙÙÙ
ت٠ÙÙ
ÙÙÙØ§ Ù
ÙØ§Ø±Ùت٠Ù
ع `undefined`:
+=======
+In the example above, `anotherFunction()` isn't called at all, if the `text` parameter is provided.
+
+On the other hand, it's independently called every time when `text` is missing.
+```
+
+````smart header="Default parameters in old JavaScript code"
+Several years ago, JavaScript didn't support the syntax for default parameters. So people used other ways to specify them.
+
+Nowadays, we can come across them in old scripts.
+
+For example, an explicit check for `undefined`:
+
+```js
+function showMessage(from, text) {
+*!*
+ if (text === undefined) {
+ text = 'no text given';
+ }
+*/!*
+
+ alert( from + ": " + text );
+}
+```
+
+...Or using the `||` operator:
+
+```js
+function showMessage(from, text) {
+ // If the value of text is falsy, assign the default value
+ // this assumes that text == "" is the same as no text at all
+ text = text || 'no text given';
+ ...
+}
+```
+````
+
+
+### Alternative default parameters
+
+Sometimes it makes sense to assign default values for parameters at a later stage after the function declaration.
+
+We can check if the parameter is passed during the function execution, by comparing it with `undefined`:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
function showMessage(text) {
+ // ...
+
*!*
- if (text === undefined) {
+ if (text === undefined) { // if the parameter is missing
text = 'empty message';
}
*/!*
@@ -236,19 +326,32 @@ showMessage(); // empty message
...Ø£Ù ÙØ³ØªØ®Ø¯Ù
Ø§ÙØ¹Ø§Ù
Ù `||`:
```js
+<<<<<<< HEAD
// إذا ÙÙ
ÙØªÙ
تÙ
Ø±ÙØ± ÙÙÙ
Ø© text أ٠تÙ
تÙ
Ø±ÙØ± "" ÙØ¬Ø¹Ù ÙÙÙ
ت٠'empty'
+=======
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
function showMessage(text) {
+ // if text is undefined or otherwise falsy, set it to 'empty'
text = text || 'empty';
...
}
```
+<<<<<<< HEAD
Ù
ØØ±Ùات Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت Ø§ÙØØ¯ÙØ«Ø© تدعÙ
[nullish coalescing operator](info:nullish-coalescing-operator) `??`ÙÙÙØ£Ùض٠ÙÙ Ø§ÙØªØ¹Ø§Ù
Ù Ù
ع falsy values Ù
ث٠`0`:
```js run
// إذا ÙÙ
ÙÙØ¬Ø¯ ÙÙÙ
Ø© "count" ÙØ¹Ø±Ø¶ "unknown"
function showCount(count) {
alert(count ?? "unknown");
+=======
+Modern JavaScript engines support the [nullish coalescing operator](info:nullish-coalescing-operator) `??`, it's better when most falsy values, such as `0`, should be considered "normal":
+
+```js run
+function showCount(count) {
+ // if count is undefined or null, show "unknown"
+ alert(count ?? "unknown");
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
}
showCount(0); // 0
@@ -411,9 +514,15 @@ checkPermission(..) // checks a permission, returns true/false
```smart header="Ø§ÙØ§Ø³Ù
اء اÙÙØµÙرة Ø¬Ø¯ÙØ§"
Ø§ÙØ¯ÙØ§Ù Ø§ÙØªÙ تستخدÙ
Ø¨ÙØ«Ø±Ø© ØºØ§ÙØ¨Ùا ÙØªÙ
Ø¥Ø¹Ø·Ø§Ø¦ÙØ§ اسÙ
ÙØµÙر.
+<<<<<<< HEAD
عÙ٠سبÙ٠اÙÙ
ثا٠Ù
ÙØªØ¨Ø© [jQuery](http://jquery.com) ØªØ¹Ø±Ù Ø¯Ø§ÙØ© اسÙ
ÙØ§ `$`. ÙÙ
ÙØªØ¨Ø© [Lodash](http://lodash.com/) ÙØ¯ÙÙØ§ Ø¯Ø§ÙØ© اسÙ
ÙØ§ `_`.
ÙØ°Ù Ù
جرد Ø§Ø³ØªØ«ÙØ§Ø¡Ø§Øª ÙÙÙ Ø§ÙØ¹Ù
ÙÙ
ÙØ¬Ø¨ Ø£Ù ÙÙÙ٠اسÙ
Ø§ÙØ¯Ø§ÙØ© Ù
Ø¹Ø¨Ø±ÙØ§.
+=======
+For example, the [jQuery](https://jquery.com/) framework defines a function with `$`. The [Lodash](https://lodash.com/) library has its core function named `_`.
+
+These are exceptions. Generally function names should be concise and descriptive.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
## Ø§ÙØ¯Ùا٠== تعÙÙÙØ§Øª
@@ -478,7 +587,11 @@ function name(parameters, delimited, by, comma) {
ÙØ¬Ø¹Ù اÙÙÙØ¯ Ø£ÙØ¶Ù ÙØ£Ø³ÙÙ ÙÙØµØ باستخداÙ
اÙÙ
ØªØºÙØ±Ø§Øª اÙÙ
ØÙÙØ© ÙØªØ¬Ø¨Ù استخداÙ
اÙÙ
ØªØºÙØ±Ø§Øª Ø§ÙØ®Ø§Ø±Ø¬ÙØ©.
+<<<<<<< HEAD
Ù
Ù Ø§ÙØ³ÙÙ ÙÙÙ
Ø§ÙØ¯ÙØ§Ù Ø§ÙØªÙ ØªØØµÙ عÙÙ ÙÙÙ
ÙØªØ¹Ù
٠عÙÙÙØ§ ÙØªØ±Ø¬Ø¹ ÙØªÙجة Ø£ÙØ«Ø± Ù
Ù Ø§ÙØ¯ÙØ§Ù Ø§ÙØªÙ تعÙ
٠عÙÙ Ù
ØªØºÙØ±Ø§Øª Ø®Ø§Ø±Ø¬ÙØ§ ÙØªØ¹Ø¯Ù عÙÙÙÙ
.
+=======
+It is always easier to understand a function which gets parameters, works with them and returns a result than a function which gets no parameters, but modifies outer variables as a side effect.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
تسÙ
ÙØ© Ø§ÙØ¯ÙاÙ:
diff --git a/1-js/02-first-steps/16-function-expressions/article.md b/1-js/02-first-steps/16-function-expressions/article.md
index f546a28ad..27a702912 100644
--- a/1-js/02-first-steps/16-function-expressions/article.md
+++ b/1-js/02-first-steps/16-function-expressions/article.md
@@ -12,7 +12,13 @@ function sayHi() {
ÙÙØ§Ù طرÙÙØ© Ø£Ø®Ø±Ù ÙØ¹Ù
Ù Ø¯Ø§ÙØ© ÙØªØ³Ù
Ù _Function Expression_.
+<<<<<<< HEAD
ÙØ§ÙتاÙÙ:
+=======
+It allows us to create a new function in the middle of any expression.
+
+For example:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
let sayHi = function () {
@@ -20,9 +26,25 @@ let sayHi = function () {
};
```
+<<<<<<< HEAD
ÙÙØ§ تÙ
عÙ
Ù Ø§ÙØ¯Ø§ÙØ© ÙØªØ®Ø²ÙÙÙØ§ ÙÙ Ù
ØªØºÙØ± Ù
ث٠أ٠ÙÙÙ
Ø© أخر٠ÙÙØ§ ÙÙÙ
ÙÙ٠تÙ
تعرÙÙÙØ§. ÙÙ ÙÙØ· تخز٠ÙÙ Ù
ØªØºÙØ± اسÙ
Ù `sayHi`.
Ù
عÙÙ ÙØ°Ø§ اÙÙÙØ¯ ÙØ§ÙآتÙ: "Ø¥ÙØ´Ø¦ Ø¯Ø§ÙØ©ÙØ¶Ø¹ÙØ§ Ù٠اÙÙ
ØªØºÙØ± `sayHi`".
+=======
+Here we can see a variable `sayHi` getting a value, the new function, created as `function() { alert("Hello"); }`.
+
+As the function creation happens in the context of the assignment expression (to the right side of `=`), this is a *Function Expression*.
+
+Please note, there's no name after the `function` keyword. Omitting a name is allowed for Function Expressions.
+
+Here we immediately assign it to the variable, so the meaning of these code samples is the same: "create a function and put it into the variable `sayHi`".
+
+In more advanced situations, that we'll come across later, a function may be created and immediately called or scheduled for a later execution, not stored anywhere, thus remaining anonymous.
+
+## Function is a value
+
+Let's reiterate: no matter how the function is created, a function is a value. Both examples above store a function in the `sayHi` variable.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
ÙÙÙØ§ ØØªÙ طباعة ÙØ°Ù اÙÙÙÙ
Ø© باستخداÙ
`alert`:
@@ -64,21 +86,35 @@ sayHi(); // Hello // this still works too (why wouldn't it)
2. Ø§ÙØ³Ø·Ø± `(2)` ÙÙØ³Ø®Ùا Ø¥ÙÙ Ù
ØªØºÙØ± اسÙ
Ù `func`. ÙØ§ØØ¸ عدÙ
ÙØ¬Ùد Ø£ÙÙØ§Ø³ بعد `sayHi`. إذا ÙØ¬Ø¯Øª Ø§ÙØ£ÙÙØ§Ø³ `func = sayHi()` Ø³ÙØªÙ
ÙØ¶Ø¹ ÙØªÙجة تÙÙÙØ° `sayHi()` داخ٠`func` ÙÙÙØ³ Ø§ÙØ¯Ø§ÙØ© `sayHi` ÙÙØ³Ùا.
3. Ø§ÙØ¢Ù ÙÙ
ÙÙÙØ§ استدعاء Ø§ÙØ¯Ø§ÙØ© ع٠طرÙÙ `sayHi()` Ø£Ù `func()`.
+<<<<<<< HEAD
ÙØ§ØØ¸ Ø£ÙÙ ÙÙ
ÙÙÙØ§ استخداÙ
Function Expression ÙØªØ¹Ø±ÙÙ `sayHi` ÙÙ Ø§ÙØ³Ø·Ø± Ø§ÙØ£ÙÙ:
```js
let sayHi = function () {
alert("Hello");
+=======
+We could also have used a Function Expression to declare `sayHi`, in the first line:
+
+```js
+let sayHi = function() { // (1) create
+ alert( "Hello" );
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
};
-let func = sayHi;
+let func = sayHi; //(2)
// ...
```
Ù٠شئ ÙØ¹Ù
٠بÙÙØ³ Ø§ÙØ·Ø±ÙÙØ©.
+<<<<<<< HEAD
````smart header="ÙÙ
اذا ÙÙØ¬Ø¯ ÙØ§ØµÙØ© Ù
ÙÙÙØ·Ø© Ù٠اÙÙÙØ§ÙØ© ?"
ربÙ
ا تتسائ٠ÙÙ
اذا ÙÙØ¬Ø¯ ÙØ§ØµÙØ© Ù
ÙÙÙØ·Ø© ÙÙ ÙÙØ§ÙØ© Function Expression ÙÙØ§ ÙÙØ¬Ø¯ Ù
ع Function Declaration:
+=======
+
+````smart header="Why is there a semicolon at the end?"
+You might wonder, why do Function Expressions have a semicolon `;` at the end, but Function Declarations do not:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
function sayHi() {
@@ -90,9 +126,15 @@ let sayHi = function() {
}*!*;*/!*
```
+<<<<<<< HEAD
Ø§ÙØ¥Ø¬Ø§Ø¨Ø© Ø¨Ø³ÙØ·Ø©:
- ÙØ§ ØØ§Ø¬Ø© ÙÙÙØ§ØµÙØ© اÙÙ
ÙÙÙØ·Ø© `;` ÙÙ ÙÙØ§ÙØ© code blocks ÙØ§ÙÙÙØ§Ù٠اÙÙ
Ø´Ø§Ø¨ÙØ© Ù
ث٠`if { ... }`, `for { }`, `function f { }` Ø§ÙØ®.
- ÙØªÙ
استخداÙ
Function Expression Ø¯Ø§Ø®Ù Ø§ÙØªØ¹Ø¨Ùر: `let sayHi = ...;` ÙÙÙÙ
Ø© ÙÙÙØ³ code block. ÙÙØ¶Ù استخداÙ
اÙÙØ§ØµÙØ© اÙÙ
ÙÙÙØ·Ø© `;` ÙÙ ÙÙØ§ÙØ© Ø§ÙØªØ¹Ø¨Ùرات Ù
ÙÙ
ا ÙØ§Ùت اÙÙÙÙ
Ø©. ÙØ°ÙÙ ÙØ§ÙÙØ§ØµÙØ© اÙÙ
ÙÙÙØ·Ø© ÙÙØ§ ÙØ§ تخص Function Expression ÙÙØ³Ù ÙÙÙÙÙØ§ ÙÙØ· تÙÙÙ Ø§ÙØªØ¹Ø¨Ùر.
+=======
+The answer is simple: a Function Expression is created here as `function(â¦) {â¦}` inside the assignment statement: `let sayHi = â¦;`. The semicolon `;` is recommended at the end of the statement, it's not a part of the function syntax.
+
+The semicolon would be there for a simpler assignment, such as `let sayHi = 5;`, and it's also there for a function assignment.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
````
## Callback functions
@@ -132,13 +174,21 @@ function showCancel() {
ask("Do you agree?", showOk, showCancel);
```
+<<<<<<< HEAD
ÙØ°Ù Ø§ÙØ¯Ùا٠Ù
ÙÙØ¯Ø© Ø¥ÙÙ ØØ¯ Ù
ا. اÙÙØ±Ù Ø§ÙØ£Ø³Ø§Ø³Ù بÙÙ `ask` Ù٠اÙÙØ§Ùع ÙØ§ÙÙ
Ø«Ø§Ù Ø§ÙØ³Ø§Ø¨Ù Ù٠أ٠Ù٠اÙÙØ§Ùع ÙØªÙ
استخداÙ
Ø·Ø±Ù Ø£ÙØ«Ø± تعÙÙØ¯Ùا ÙÙØªØ¹Ø§Ù
Ù Ù
ع اÙÙ
ستخدÙ
بدÙÙØ§ Ù
Ù Ù
جرد `confirm`. ربÙ
ا ÙØªÙ
رسÙ
ÙØ§Ùذة سؤا٠بشÙÙ ÙØ·ÙÙ ÙÙÙÙ ÙØ°Ù ÙØµØ© أخرÙ.
+=======
+In practice, such functions are quite useful. The major difference between a real-life `ask` and the example above is that real-life functions use more complex ways to interact with the user than a simple `confirm`. In the browser, such functions usually draw a nice-looking question window. But that's another story.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
**اÙÙ
عاÙ
ÙØ§Øª `showOk` Ù `showCancel` Ø§ÙØ®Ø§ØµÙ٠ب `ask` ÙØ³Ù
ÙÙ _callback functions_ Ø£Ù ÙÙØ· _callbacks_.**
اÙÙÙØ±Ø© Ù٠أÙÙØ§ ÙÙÙÙ
بتÙ
Ø±ÙØ± Ø¯Ø§ÙØ© ÙÙØªÙÙØ¹ Ø£Ù ÙØªÙ
Ø§Ø³ØªØ¯Ø¹Ø§Ø¦ÙØ§ ÙØ§ØÙÙØ§ إذا ÙØ²Ù
Ø§ÙØ£Ù
ر. ÙÙÙ ØØ§ÙØªÙØ§ ÙØ¥Ù `showOk` ØªØµØ¨Ø Ø±Ø¯ عÙÙ Ø§ÙØ¥Ø¬Ø§Ø¨Ø© "yes" answer Ù `showCancel` ÙÙØ¥Ø¬Ø§Ø¨Ø© "no".
+<<<<<<< HEAD
ÙÙ
Ù٠استخداÙ
Function Expressions ÙÙØªØ§Ø¨Ø© ÙÙØ³ Ø§ÙØ¯Ø§ÙØ© بشÙÙ Ø£ÙØµØ±:
+=======
+We can use Function Expressions to write an equivalent, shorter function:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run no-beautify
function ask(question, yes, no) {
@@ -173,7 +223,11 @@ ask(
Ø£ÙÙØ§ طرÙÙØ© اÙÙØªØ§Ø¨Ø©: ÙÙÙ ØªÙØ±Ù بÙÙÙÙ
Ù٠اÙÙÙØ¯.
+<<<<<<< HEAD
- _Function Declaration:_ ÙØªÙ
تعرÙÙ Ø§ÙØ¯Ø§ÙØ© ÙØ¬Ø²Ø¡ Ù
ÙÙØµÙ ÙÙ Ø³Ø±ÙØ§Ù Ø§ÙØ¨Ø±ÙاÙ
ج.
+=======
+- *Function Declaration:* a function, declared as a separate statement, in the main code flow:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
// Function Declaration
@@ -181,8 +235,12 @@ ask(
return a + b;
}
```
+<<<<<<< HEAD
- _Function Expression:_ ÙØªÙ
Ø¥ÙØ´Ø§Ø¡ Ø§ÙØ¯Ø§ÙØ© Ø¯Ø§Ø®Ù ØªØ¹Ø¨ÙØ± أ٠جزء آخر. ÙÙØ§ تÙ
Ø¥ÙØ´Ø§Ø¡ Ø§ÙØ¯Ø§ÙØ© ÙÙ Ø§ÙØ¬Ø²Ø¡ Ø§ÙØ£ÙÙ
Ù Ù
Ù "assignment expression" `=`:
+=======
+- *Function Expression:* a function, created inside an expression or inside another syntax construct. Here, the function is created on the right side of the "assignment expression" `=`:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
// Function Expression
@@ -349,7 +407,12 @@ welcome(); // ok now
```smart header="Ù
ØªÙ ÙØ³ØªØ®Ø¯Ù
Function Declaration أ٠Function Expression?"
Ø¹ÙØ¯Ù
ا ÙØ±Ùد عÙ
Ù Ø¯Ø§ÙØ© ÙØ£ÙÙ Ù
ا ÙØ¬Ø¨ Ø£Ù ÙÙÙØ± ÙÙÙ ÙÙ Function Declaration ÙÙÙ ÙØ¹Ø·ÙÙØ§ ØØ±ÙØ© Ø£ÙØ«Ø± ÙØªÙظÙÙ
اÙÙÙØ¯ ÙØ£Ù ÙÙ
ÙÙÙØ§ استخداÙ
Ø§ÙØ¯Ø§ÙØ© ÙØ¨Ù تعرÙÙÙØ§.
+<<<<<<< HEAD
ÙÙØ°Ø§ Ø£ÙØ¶Ù Ù
Ù ÙØ§ØÙØ© ÙØ±Ø§Ø¡Ø© اÙÙÙØ¯ ÙÙ
Ù Ø§ÙØ£Ø³ÙÙ Ù
ÙØ§ØØ¸Ø© `function f(â¦) {â¦}` ع٠`let f = function(â¦) {â¦};`..
+=======
+```smart header="When to choose Function Declaration versus Function Expression?"
+As a rule of thumb, when we need to declare a function, the first thing to consider is Function Declaration syntax. It gives more freedom in how to organize our code, because we can call such functions before they are declared.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
...ÙÙÙ٠إذا ÙØ§Ù Function Declaration ØºÙØ± Ù
ÙØ§Ø³Ø¨ ÙØ³Ø¨Ø¨ Ù
ا Ø£Ù ÙØ±Ùد تعرÙÙ Ø¯Ø§ÙØ© Ø¨ÙØ§Ø¡Ùا عÙ٠شرط Ù
عÙÙ ÙÙ
ا رأÙÙØ§ سابÙÙØ§ ÙØ¹ÙØ¯ÙØ§ ÙØ¬Ø¨ استخداÙ
Function Expression.
```
diff --git a/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/solution.md b/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/solution.md
index 935ed23f8..516d76cec 100644
--- a/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/solution.md
+++ b/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/solution.md
@@ -1,6 +1,6 @@
```js run
function ask(question, yes, no) {
- if (confirm(question)) yes()
+ if (confirm(question)) yes();
else no();
}
diff --git a/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/task.md b/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/task.md
index ef8576c11..769feafb0 100644
--- a/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/task.md
+++ b/1-js/02-first-steps/17-arrow-functions-basics/1-rewrite-arrow/task.md
@@ -4,8 +4,13 @@
```js run
function ask(question, yes, no) {
+<<<<<<< HEAD
if (confirm(question)) yes();
else no();
+=======
+ if (confirm(question)) yes();
+ else no();
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
}
ask(
diff --git a/1-js/02-first-steps/17-arrow-functions-basics/article.md b/1-js/02-first-steps/17-arrow-functions-basics/article.md
index 578d205bc..7dc09b88f 100644
--- a/1-js/02-first-steps/17-arrow-functions-basics/article.md
+++ b/1-js/02-first-steps/17-arrow-functions-basics/article.md
@@ -5,10 +5,14 @@
تسÙ
Ù "arrow functions" ÙØ£ÙÙØ§ ØªØ´Ø¨Ù Ø§ÙØ³ÙÙ
:
```js
-let func = (arg1, arg2, ..., argN) => expression
+let func = (arg1, arg2, ..., argN) => expression;
```
+<<<<<<< HEAD
...ÙØ°Ø§ ÙÙØ´Ø¦ Ø¯Ø§ÙØ© `func` تأخذ ÙÙÙ
`arg1..argN` ÙØªÙÙØ° `expression` Ø§ÙØ·Ø±Ù Ø§ÙØ£ÙÙ
٠باستخداÙ
ÙÙ
ÙØªØ±Ø¬Ø¹ اÙÙØªÙجة.
+=======
+This creates a function `func` that accepts arguments `arg1..argN`, then evaluates the `expression` on the right side with their use and returns its result.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¨ØµÙØºØ© أخر٠ÙÙ٠إختصار Ù:
@@ -33,7 +37,11 @@ let sum = function(a, b) {
alert(sum(1, 2)); // 3
```
+<<<<<<< HEAD
ÙÙ
ا ØªØ±Ù ÙØ¥Ù `(a, b) => a + b` تعÙÙ Ø£Ù Ø§ÙØ¯Ø§ÙØ© ØªØ³ØªÙØ¨Ù ÙÙÙ
تÙÙ `a` Ù `b`. ÙØªÙÙØ° Ø§ÙØªØ¹Ø¨Ùر `a + b` ÙØªØ±Ø¬Ø¹ ÙØªÙجتÙ.
+=======
+As you can see, `(a, b) => a + b` means a function that accepts two arguments named `a` and `b`. Upon the execution, it evaluates the expression `a + b` and returns the result.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
- إذا ÙØ§Ù ÙØ¯ÙÙ Ù
عاÙ
Ù ÙØ§ØØ¯ ÙÙØ· ÙÙÙ
ÙÙ ØØ°Ù Ø§ÙØ£ÙÙØ§Ø³ Ø§ÙØ¯Ø§Ø¦Ø±ÙØ© Ù
Ù ØÙÙÙ ÙØ¬Ø¹Ù Ø§ÙØªØ¹Ø¨Ùر Ø£ÙØµØ±.
@@ -48,7 +56,11 @@ alert(sum(1, 2)); // 3
alert( double(3) ); // 6
```
+<<<<<<< HEAD
- إذا ÙÙ
ÙÙØ¬Ø¯ Ù
عاÙ
ÙØ§Øª ÙØªÙ
ØªØ±Ù Ø§ÙØ£ÙÙØ§Ø³ ÙØ§Ø±ØºØ© (ÙÙÙÙ ÙØ¬Ø¨ ÙØªØ§Ø¨ØªÙا):
+=======
+- If there are no arguments, parentheses are empty, but they must be present:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let sayHi = () => alert("Hello!");
@@ -63,7 +75,13 @@ alert(sum(1, 2)); // 3
```js run
let age = prompt("What is your age?", 18);
+<<<<<<< HEAD
let welcome = age < 18 ? () => alert("Hello") : () => alert("Greetings!");
+=======
+let welcome = (age < 18) ?
+ () => alert('Hello!') :
+ () => alert("Greetings!");
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
welcome();
```
@@ -74,9 +92,15 @@ welcome();
## Multiline arrow functions
+<<<<<<< HEAD
اÙÙ
Ø«Ø§Ù Ø¨Ø§ÙØ£Ø¹ÙÙ ÙØ£Ø®Ø° اÙÙÙÙ
عÙÙ ÙØ³Ø§Ø± `=>` ÙÙÙÙØ° Ø§ÙØªØ¹Ø¨Ùر عÙ٠اÙÙÙ
Ù٠باستخداÙ
ÙÙ
.
Ø£ØÙاÙÙØ§ ÙØ±Ùد شئ Ø£ÙØ«Ø± تعÙÙØ¯Ùا ÙØªÙÙÙØ° عدة Ø£ÙØ§Ù
ر. Ø¹ÙØ¯Ùا ÙÙ
ÙÙ ÙØµØ¹ÙÙ
داخ٠أÙÙØ§Ø³ Ù
عÙÙÙØ© ÙÙÙÙ ÙØ¬Ø¨ استخداÙ
`return` Ø§ÙØ·Ø¨ÙØ¹ÙØ© Ù
عÙÙ
.
+=======
+The arrow functions that we've seen so far were very simple. They took arguments from the left of `=>`, evaluated and returned the right-side expression with them.
+
+Sometimes we need a more complex function, with multiple expressions and statements. In that case, we can enclose them in curly braces. The major difference is that curly braces require a `return` within them to return a value (just like a regular function does).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Like this:
@@ -103,7 +127,14 @@ Arrow functions ÙØ¯ÙÙØ§ Ø§ÙØ¹Ø¯Ùد Ù
٠اÙÙ
Ù
ÙØ²Ø§Øª Ø§ÙØ´ÙÙØ©.
## Ù
ÙØ®Øµ
+<<<<<<< HEAD
Arrow functions ØªØ£ØªÙ Ø¨ØµÙØºØªÙÙ:
1. بدÙ٠أÙÙØ§Ø³ Ù
عÙÙÙØ©: `(...args) => expression` -- تÙÙÙ
Ø§ÙØ¯Ø§ÙØ© بتÙÙÙØ° Ø§ÙØªØ¹Ø¨Ùر اÙÙ
ÙØ¬Ùد Ø¨Ø§ÙØ¬Ø²Ø¡ Ø§ÙØ£ÙÙ
Ù ÙØªØ±Ø¬Ø¹ ÙØªÙØØªÙ.
2. Ù
ع Ø£ÙÙØ§Ø³ Ù
عÙÙÙØ©: `(...args) => { body }` -- تسÙ
Ø ÙÙØ§ بتÙÙÙØ° Ø£ÙØ«Ø± Ù
٠أÙ
ر ÙÙÙÙ ÙØ¬Ø¨ ÙØ¶Ø¹ `return` ÙÙÙ ÙØ±Ø¬Ø¹ ÙÙÙ
Ø© Ù
ا.
+=======
+Arrow functions are handy for simple actions, especially for one-liners. They come in two flavors:
+
+1. Without curly braces: `(...args) => expression` -- the right side is an expression: the function evaluates it and returns the result. Parentheses can be omitted, if there's only a single argument, e.g. `n => n*2`.
+2. With curly braces: `(...args) => { body }` -- brackets allow us to write multiple statements inside the function, but we need an explicit `return` to return something.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/02-first-steps/18-javascript-specials/article.md b/1-js/02-first-steps/18-javascript-specials/article.md
index 7b3fbcd8c..c2f5a3829 100644
--- a/1-js/02-first-steps/18-javascript-specials/article.md
+++ b/1-js/02-first-steps/18-javascript-specials/article.md
@@ -55,7 +55,11 @@ for(;;) {
ÙØ¬Ø¨ ÙØ¶Ø¹ ÙØ°Ù Ø§ÙØªØ¹ÙÙÙ
Ø© Ø£Ù Ø§ÙØªÙجÙÙ Ù٠أعÙ٠اÙÙØµ Ø§ÙØ¨Ø±Ù
ج٠أ٠ÙÙ Ø¨Ø¯Ø§ÙØ© جسÙ
Ø§ÙØªØ§Ø¨Ø¹.
+<<<<<<< HEAD
ÙØ¨Ø¯ÙÙ ÙØ¶Ø¹ Ø§ÙØªØ¹ÙÙÙ
Ø© `"use strict"`Ø Ø³ÙØ¹Ù
Ù ÙÙ Ø´ÙØ¡ عÙÙ Ù
ا ÙØ±Ø§Ù
Ø ÙÙÙ٠ستعÙ
٠بعض اÙÙ
ÙØ²Ø§Øª بأسÙÙØ¨Ùا اÙÙØ¯ÙÙ
اÙÙ
ØªÙØ§ÙÙ Ù
ع Ø§ÙØ³ÙÙÙ Ø§ÙØØ¯ÙØ«. ÙØ°ÙÙ ÙÙÙØ¶Ù عÙ
ÙÙ
ا٠استخداÙ
ÙØ°Ø§ Ø§ÙØ£Ø³ÙÙØ¨ Ø§ÙØ£ØØ¯Ø«.
+=======
+Without `"use strict"`, everything still works, but some features behave in the old-fashioned, "compatible" way. We'd generally prefer the modern behavior.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¬Ø¯ÙØ±Ù Ø¨Ø§ÙØ°ÙØ±Ø Ø£Ù Ø¨Ø¹Ø¶Ø§Ù Ù
Ù ÙØ°Ù اÙÙ
ÙØ²Ø§Øª (ÙØ§ÙصÙÙÙ Ø§ÙØªÙ Ø³ÙØ¯Ø±Ø³Ùا Ù٠اÙÙ
Ø³ØªÙØ¨Ù) تÙÙÙ
Ø¨ØªÙØ¹ÙÙ ÙØ°Ø§ اÙÙØ¶Ø¹ Ø§ÙØØ¯ÙØ« (Ø§ÙØ¯ÙÙÙ) بشÙ٠ضÙ
ÙÙ ØØªÙ ÙÙ ÙÙ
ÙØªÙ
ÙØªØ§Ø¨Ø© Ø§ÙØªØ¹ÙÙÙ
Ø© بشÙÙ ØµØ±ÙØ.
@@ -103,6 +107,7 @@ typeof function(){} == "function" // ÙØªÙ
Ù
Ø¹Ø§ÙØ¬Ø© Ø§ÙØªÙابع بشÙÙ
ÙØÙ ÙØ³ØªØ®Ø¯Ù
اÙÙ
ØªØµÙØ ÙØ¨Ùئة عÙ
ÙØ ÙØ°Ø§ تÙÙÙ ÙØ§Ø¬Ùات اÙÙ
ستخدÙ
Ø§ÙØ£Ø³Ø§Ø³ÙØ© ÙÙØªÙاع٠Ù
ع٠ÙÙ:
+<<<<<<< HEAD
[`prompt(question, [default])`](mdn:api/Window/prompt)
: ع٠طرÙÙ ÙØ°Ù Ø§ÙØªØ¹ÙÙÙ
Ø© ÙØªÙ
Ø·Ø±Ø Ø³Ø¤Ø§Ù Ø¹Ù٠اÙÙ
ستخدÙ
Ø Ù
ع ØÙÙ ÙØµÙÙ ÙØ¥Ø¯Ø®Ø§Ù Ø§ÙØ¬Ùاب اÙÙ
ÙØ§Ø³Ø¨Ø ÙÙØªÙ
إرجاع اÙÙÙÙ
Ø© Ø§ÙØªÙ أدخÙÙØ§ اÙÙ
ستخدÙ
Ø£Ù `null` إذا ÙÙØ± عÙ٠زر Ø§ÙØ¥Ùغاء (cancel).
@@ -111,6 +116,16 @@ typeof function(){} == "function" // ÙØªÙ
Ù
Ø¹Ø§ÙØ¬Ø© Ø§ÙØªÙابع بشÙÙ
[`alert(message)`](mdn:api/Window/alert)
: تÙÙÙ
ÙØ°Ù Ø§ÙØªØ¹ÙÙÙ
Ø© Ø¨Ø¥Ø¸ÙØ§Ø± Ø±Ø³Ø§ÙØ© Ù
عÙÙÙØ© `message`.
+=======
+[`prompt(question, [default])`](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt)
+: Ask a `question`, and return either what the visitor entered or `null` if they clicked "cancel".
+
+[`confirm(question)`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm)
+: Ask a `question` and suggest to choose between Ok and Cancel. The choice is returned as `true/false`.
+
+[`alert(message)`](https://developer.mozilla.org/en-US/docs/Web/API/Window/alert)
+: Output a `message`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
جÙ
ÙØ¹ Ø§ÙØªÙابع Ø§ÙØ³Ø§Ø¨ÙØ© Ù٠عبارة ع٠Ù
ÙØ§ØØ¸Ø§Øª Ø´ÙÙÙØ© Ø£Ù ÙØªÙ
ÙØªØ ÙØ§Ùذة ØµØºÙØ±Ø© Ù٠أعÙÙ Ø§ÙØµÙØØ© ÙÙØ³Ùا ÙØªÙÙÙ
بعرض Ø§ÙØ³Ø¤Ø§ÙØ ÙØªÙÙÙ
ÙØ°Ù اÙÙ
ÙØ§ØØ¸Ø© بإÙÙØ§Ù تÙÙÙØ° اÙÙÙØ¯ Ø§ÙØ¨Ø±Ù
Ø¬Ù ÙØªÙ
ÙØ¹ اÙÙ
ستخدÙ
Ù
Ù Ø§ÙØªÙاع٠Ù
ع Ø§ÙØµÙØØ© ØØªÙ تتÙ
Ø§ÙØ¥Ø¬Ø§Ø¨Ø© عÙÙ Ø§ÙØ³Ø¤Ø§Ù اÙÙ
Ø·Ø±ÙØ.
@@ -143,8 +158,13 @@ alert( "Tea wanted: " + isTeaWanted ); // true
Ø§ÙØ¥Ø³Ùاد
: Ø§ÙØ¥Ø³Ùاد Ø§ÙØ¨Ø³ÙØ· ÙÙ Ù
Ù Ø§ÙØ´ÙÙ: `a = b` Ø£Ù
ا Ø§ÙØ¥Ø³Ùاد اÙÙ
رÙÙØ¨ ÙÙÙ Ù
Ù Ø§ÙØ´ÙÙ `a *= 2`.
+<<<<<<< HEAD
Ø¹ÙØ§Ù
Ù Ø§ÙØ¨ÙØªÙØ§Øª (Bitwise)
: تÙÙÙ
Ø¹ÙØ§Ù
٠اÙÙ Bitwise Ø¨Ø§ÙØ¹Ù
Ù Ù
ع Ø§ÙØ£Ø¹Ø¯Ø§Ø¯ Ø§ÙØµØÙØØ© Ù
Ù ÙØ¦Ø© 32-Ø¨ÙØª عÙÙ Ø§ÙØ£ÙÙØ ÙÙ٠تعÙ
٠عÙÙ Ù
ستÙÙ Ø§ÙØ¨ÙØªØ ÙÙÙØ§Ø·Ùاع عÙÙÙØ§ ÙÙ
ÙÙ Ù
راجعة [Ø§ÙØªÙØ«ÙÙ](mdn:/JavaScript/Guide/Expressions_and_Operators#Bitwise) Ø¹ÙØ¯ Ø§ÙØØ§Ø¬Ø©.
+=======
+Bitwise
+: Bitwise operators work with 32-bit integers at the lowest, bit-level: see the [docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise_operators) when they are needed.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø§ÙØ¹ÙاÙ
Ù Ø§ÙØ´Ø±Ø·ÙØ©
: ÙØ§ÙعاÙ
Ù Ø§ÙØ´Ø±Ø·Ù ÙÙ Ø§ÙØ¹Ø§Ù
٠اÙÙØÙØ¯ Ø§ÙØ°Ù ÙØ£Ø®Ø° Ø«ÙØ§Ø« Ù
عاÙ
ÙØ§Øª: `cond ? resultA : resultB`. ÙØ¥Ø°Ø§ ÙØ§Ù Ø§ÙØ´Ø±Ø· `cond` صØÙØØ§ÙØ Ø³ÙØªÙ
٠إرجاع `resultA` ÙØ¥Ùا Ø³ÙØªÙ
إرجاع `resultB`.
@@ -256,7 +276,11 @@ switch (age) {
3. Ø§ÙØ¯ÙØ§Ù ÙØ£Ø³ÙÙ
: (ØÙØ« ØªÙØ±Ø³Ù
Ø§ÙØ¯Ùا٠بطرÙÙØ© تشب٠شÙÙ Ø§ÙØ³ÙÙ
)
```js
+<<<<<<< HEAD
// ØªÙØ¶Ø¹ Ø§ÙØªØ¹Ø§Ø¨Ùر ÙÙ Ø§ÙØ·Ø±Ù اÙÙÙ
ÙÙÙ
+=======
+ // expression on the right side
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
let sum = (a, b) => a + b;
// Ø£Ù ÙÙ
Ù٠استخداÙ
Ø£ÙØ«Ø± Ù
٠سطر Ù
ع Ø£ÙÙØ§Ø³ اÙÙØªÙ {...}
diff --git a/1-js/03-code-quality/01-debugging-chrome/article.md b/1-js/03-code-quality/01-debugging-chrome/article.md
index 1f969765a..34db90d91 100644
--- a/1-js/03-code-quality/01-debugging-chrome/article.md
+++ b/1-js/03-code-quality/01-debugging-chrome/article.md
@@ -1,4 +1,8 @@
+<<<<<<< HEAD
# تصØÙØ Ø§ÙØ£Ø®Ø·Ø§Ø¡ ÙÙ ÙØ±ÙÙ
+=======
+# Debugging in the browser
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ¨Ù ÙØªØ§Ø¨Ø© Ø£Ù ÙÙØ¯ Ù
Ø¹ÙØ¯ , ÙÙÙØªØØ¯Ø« ÙÙÙÙØ§ ع٠تصØÙØ Ø§ÙØ£Ø®Ø·Ø§Ø¡.
@@ -40,7 +44,11 @@ The Sources panel has 3 parts:
بعد Ø§Ù ÙØªÙ
تÙÙÙØ° Ø§ÙØ£Ù
ر, اÙÙØ§ØªØ¬ ÙØ¸Ùر اسÙÙÙ.
+<<<<<<< HEAD
ÙÙ
ثاÙ, ÙÙØ§ `1+2` ÙÙØªØ¬ عÙÙØ§ `3` Ù `hello("debugger")` ÙØ§ ÙÙØªØ¬ عÙÙØ§ شئ, ÙØ°Ø§ ÙØ§ÙÙØ§ØªØ¬ ÙÙÙÙ `undefined`.
+=======
+For example, here `1+2` results in `3`, while the function call `hello("debugger")` returns nothing, so the result is `undefined`:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11

@@ -64,13 +72,22 @@ The Sources panel has 3 parts:
- ÙÙ
Ø¨Ø¥Ø²Ø§ÙØ© ÙÙØ·Ø© Ø§ÙØªÙÙ٠باÙÙÙØ± بزر اÙÙ
Ø§ÙØ³ Ø§ÙØ£ÙÙ
Ù ÙØ§Ø®ØªÙار Ø¥Ø²Ø§ÙØ©.
- ...Ù ÙÙØ°Ø§.
+<<<<<<< HEAD
```smart header="ÙÙØ§Ø· Ø§ÙØªÙÙ٠اÙÙ
Ø´Ø±ÙØ·Ø©"
*اÙÙÙØ± بزر اÙÙ
Ø§ÙØ³ Ø§ÙØ£ÙÙ
Ù* عÙ٠رÙÙ
Ø§ÙØ³Ø·Ø± ÙØ³Ù
Ø Ø¨Ø¥ÙØ´Ø§Ø¡ ÙÙØ·Ø© تÙÙÙ *Ù
Ø´Ø±ÙØ·Ø©*. ÙØªÙ
تشغÙÙÙØ§ ÙÙØ· Ø¹ÙØ¯Ù
ا ÙÙÙÙ Ø§ÙØ´Ø±Ø· اÙÙ
عط٠Ù
ØÙÙ.
+=======
+```smart header="Conditional breakpoints"
+*Right click* on the line number allows to create a *conditional* breakpoint. It only triggers when the given expression, that you should provide when you create it, is truthy.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙÙÙ ÙØ°Ø§ Ù
ÙÙØ¯Ø§ Ø¹ÙØ¯ Ø§ÙØØ§Ø¬Ø© ÙÙØªÙÙÙ ÙÙØ· تبعا ÙÙ
ØªØºÙØ± Ù
عÙ٠أ٠Ù
عاÙ
ÙØ§Øª Ø¯Ø§ÙØ© Ù
عÙÙØ©.
```
+<<<<<<< HEAD
## Ø£Ù
ر Ù
ØµØØ Ø§ÙØ®Ø·Ø£(Debugger)
+=======
+## The command "debugger"
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
ÙÙÙØ§ Ø£ÙØ¶Ùا Ø¥ÙÙØ§Ù اÙÙÙØ¯ Ù
Ø¤ÙØªÙا باستخداÙ
Ø§ÙØ£Ù
ر `debugger` اÙÙ
ÙØ¬Ùد ÙÙÙ Ø ÙØ§ÙتاÙÙ:
@@ -87,9 +104,13 @@ function hello(name) {
```
ÙØ°Ø§ Ø§ÙØ£Ù
ر Ù
Ø±ÙØ ÙÙØºØ§ÙØ© Ø¹ÙØ¯Ù
ا ÙÙÙÙ ÙÙ Ù
ØØ±Ø± Ø£ÙÙØ§Ø¯ ÙÙØ§ ÙØ±Ùد Ø§ÙØªØ¨Ø¯Ù٠إÙ٠اÙÙ
ØªØµÙØ ÙØ§ÙØ¨ØØ« ع٠اÙÙØµ ÙÙ Ø£Ø¯ÙØ§Øª اÙÙ
Ø·ÙØ± ÙØªØ¹ÙÙÙ ÙÙØ·Ø© Ø§ÙØªÙÙÙ.
+<<<<<<< HEAD
## Ø§ÙØªØ¸Ø± ÙÙÙÙØ§ ÙØ§Ùظر ØÙÙÙ
ÙÙ Ù
ثاÙÙØ§ Ø `hello()` ÙØªÙ
اÙÙØ¯Ø§Ø¡ عÙÙÙØ§ Ø¹ÙØ¯ تØÙ
ÙÙ Ø§ÙØµÙØØ©, ÙØ°Ø§ اسÙ٠طرÙÙØ© ÙØªÙعÙÙ Ù
ØµØØ Ø§ÙØ£Ø®Ø·Ø§Ø¡ (بعد ÙØ¶Ø¹ ÙÙØ·Ø© Ø§ÙØªÙÙÙ) Ù٠اعادة تØÙ
ÙÙ Ø§ÙØµÙØØ©. ÙØ°Ø§ ÙØ¶ØºØ· `key:F5` (Windows, Linux) Ø£Ù `key:Cmd+R` (Mac).
+=======
+Such command works only when the development tools are open, otherwise the browser ignores it.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¹ÙØ¯ تعÙÙÙ ÙÙØ·Ø© Ø§ÙØªÙÙÙ Ø ÙØªÙÙÙ Ø§ÙØªÙÙÙØ° Ù
Ø¤ÙØªÙا Ø¹ÙØ¯ Ø§ÙØ³Ø·Ø± Ø§ÙØ±Ø§Ø¨Ø¹:
@@ -99,7 +120,11 @@ function hello(name) {
1. **`Watch` -- ÙØ¹Ø±Ø¶ اÙÙÙÙ
Ø§ÙØØ§ÙÙØ© ÙØ£Ù ØªØ¹Ø¨ÙØ±Ø§Øª.**
+<<<<<<< HEAD
ÙÙ
ÙÙÙØ§ اÙÙÙØ± ÙÙÙ Ø¹ÙØ§Ù
Ø© زائد `+` ÙØ¥Ø¯Ø®Ø§Ù ØªØ¹Ø¨ÙØ±. Ø³ÙØ¸Ùر Ù
ØµØØ Ø§ÙØ£Ø®Ø·Ø§Ø¡ ÙÙÙ
ت٠ÙÙ Ø£Ù ÙØØ¸Ø© Ø ÙÙØ¹Ùد ØØ³Ø§Ø¨Ù تÙÙØ§Ø¦ÙÙØ§ Ù٠عÙ
ÙÙØ© Ø§ÙØªÙÙÙØ°.
+=======
+ You can click the plus `+` and input an expression. The debugger will show its value, automatically recalculating it in the process of execution.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
2. **`Call Stack` -- ÙØ¹Ø±Ø¶ Ø³ÙØ³ÙØ© Ù
Ù Ø§ÙØ§Ø³ØªØ¯Ø¹Ø§Ø¡Ø§Øª اÙÙ
ترابطة.**
@@ -135,11 +160,20 @@ function hello(name) {
Ø³ÙØ¤Ø¯Ù اÙÙÙØ± عÙÙÙ Ù
رة أخر٠تÙÙ Ø§ÙØ£Ø®Ø±Ù Ø¥Ù٠استعراض ÙØ§ÙØ© عبارات اÙÙØµ ÙØ§ØØ¯Ùا تÙÙ Ø§ÙØ¢Ø®Ø±.
+<<<<<<< HEAD
-- "Ø®Ø·ÙØ© ÙÙØ£Ù
اÙ
": تÙÙÙ
بتشغÙÙ Ø§ÙØ£Ù
ر Ø§ÙØªØ§ÙÙ, ÙÙÙ *ÙØ§ ØªØ¯Ø®Ù Ø¨Ø¯Ø§Ø®Ù Ø§ÙØ¯Ø§ÙØ©*, Ø²Ø±Ù Ø§ÙØ³Ø±Ùع `key:F10`.
: ÙØ´Ø¨Ù Ø§ÙØ£Ù
ر "Ø®Ø·ÙØ©" Ø§ÙØ³Ø§Ø¨Ù Ø ÙÙÙÙÙ ÙØªØµØ±Ù بشÙÙ Ù
ختÙ٠إذا ÙØ§Ùت Ø§ÙØ¹Ø¨Ø§Ø±Ø© Ø§ÙØªØ§ÙÙØ© Ù٠استدعاء Ø¯Ø§ÙØ©. اذا ÙÙ
تÙÙ Ø¯Ø§ÙØ© Ù
دÙ
جة Ø Ù
ث٠`alert`Ø ÙÙÙÙÙØ§ Ø¯Ø§ÙØ© Ù
Ù Ø§ÙØ´Ø§Ø¡Ùا.
ÙÙØªÙÙ Ø§ÙØ£Ù
ر "Ø®Ø·ÙØ©" Ø¥ÙÙÙ ÙÙÙÙÙ Ø§ÙØªÙÙÙØ° Ø¹ÙØ¯ Ø§ÙØ³Ø·Ø± Ø§ÙØ£ÙÙ Ù
Ø¤ÙØªÙا Ø Ø¨ÙÙÙ
ا ÙÙÙÙ
"Ø®Ø·ÙØ© ÙÙØ£Ù
اÙ
" باستدعاء Ø§ÙØ¯Ø§ÙØ© اÙÙ
ØªØ¯Ø§Ø®ÙØ© بشÙÙ ØºÙØ± Ù
Ø±Ø¦Ù Ø Ù
ع ØªØ®Ø·Ù Ø§ÙØ¯ÙØ§Ù Ø§ÙØ¯Ø§Ø®ÙÙØ©.
+=======
+ -- "Step over": run the next command, but *don't go into a function*, hotkey `key:F10`.
+: Similar to the previous "Step" command, but behaves differently if the next statement is a function call (not a built-in, like `alert`, but a function of our own).
+
+ If we compare them, the "Step" command goes into a nested function call and pauses the execution at its first line, while "Step over" executes the nested function call invisibly to us, skipping the function internals.
+
+ The execution is then paused immediately after that function call.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØªÙ
Ø¥ÙÙØ§Ù Ø§ÙØªÙÙÙØ° بعد ذÙÙ Ù
باشرة بعد ÙØ°Ù Ø§ÙØ¯Ø§ÙØ©.
@@ -151,7 +185,12 @@ function hello(name) {
ÙÙÙ
Ø¹Ø±ÙØ© Ù
Ø³ØªÙØ¨Ùا Ø ÙØ§ØØ¸ ÙÙØ· Ø£Ù Ø§ÙØ£Ù
ر "Ø®Ø·ÙØ©" ÙØªØ¬Ø§ÙÙ Ø§ÙØ¥Ø¬Ø±Ø§Ø¡Ø§Øª ØºÙØ± اÙÙ
تزاÙ
ÙØ© Ø Ù
ث٠`setTimeout` (ÙØ¯Ø§Ø¡ Ø§ÙØ¯Ùا٠اÙÙ
جدÙÙØ©) Ø Ø§ÙØªÙ ÙØªÙ
تÙÙÙØ°Ùا ÙØ§ØÙÙØ§. تدخ٠"Ø§ÙØ®Ø·ÙØ© ÙÙØ¯Ø§Ø®Ù" Ù٠اÙÙÙØ¯ Ø§ÙØ®Ø§Øµ بÙÙ
ØÙ ØªÙØªØ¸Ø±ÙÙ
إذا ÙØ²Ù
Ø§ÙØ£Ù
ر.
+<<<<<<< HEAD
ÙÙ
Ø²ÙØ¯ Ù
Ù Ø§ÙØªÙاصÙÙ , Ø§ØªØ·ÙØ¹ عÙÙ [DevTools manual](https://developers.google.com/web/updates/2018/01/devtools#async).
+=======
+ -- enable/disable automatic pause in case of an error.
+: When enabled, if the developer tools is open, an error during the script execution automatically pauses it. Then we can analyze variables in the debugger to see what went wrong. So if our script dies with an error, we can open debugger, enable this option and reload the page to see where it dies and what's the context at that moment.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
-- "Ø®Ø·ÙØ© ÙÙØ®Ø§Ø±Ø¬": تابع Ø§ÙØªÙÙÙØ° ØØªÙ ÙÙØ§ÙØ© Ø§ÙØ¯Ø§ÙØ© Ø§ÙØØ§ÙÙØ© Ø Ø²Ø±Ù Ø§ÙØ³Ø±Ùع `key:Shift+F11`.
: ÙØ³ØªÙ
ر ÙÙ Ø§ÙØªÙÙÙØ° ÙÙÙÙÙÙ ÙÙ Ø§ÙØ³Ø·Ø± Ø§ÙØ£Ø®Ùر Ù
Ù Ø§ÙØ¯Ø§ÙØ© Ø§ÙØØ§ÙÙØ©. ÙÙÙÙ ÙØ°Ø§ Ù
ÙÙØ¯Ø§ Ø¹ÙØ¯ Ø§ÙØ¯Ø®Ù٠اÙÙ ÙØ¯Ø§Ø¡Ø§Øª Ù
ØªØ¯Ø§Ø®ÙØ© ع٠طرÙÙ Ø§ÙØ®Ø·Ø£ ,ÙÙÙÙØ§ ÙØ§ تÙÙ
ÙØ§ Ø ÙÙØ±Ùد Ø£Ù ÙØ³ØªÙ
ر ØØªÙ ÙÙØ§ÙØªÙØ§ ÙÙ Ø£ÙØ±Ø¨ ÙÙØª Ù
Ù
ÙÙ.
@@ -195,7 +234,11 @@ for (let i = 0; i < 5; i++) {
2. عبارة Ø£Ù
ر Ù
ØµØØ Ø§ÙØ®Ø·Ø£ `debugger`.
3. خطأ (اذا ÙØ§Ùت Ø§Ø¯ÙØ§Øª اÙÙ
Ø·ÙØ± Ù
ÙØªÙØØ© ٠زر Ù
ÙØ¹Ù ا٠ÙÙÙ
ت٠"on").
+<<<<<<< HEAD
Ø¹ÙØ¯ Ø§ÙØ¥ÙÙØ§Ù اÙÙ
Ø¤ÙØª Ø ÙÙ
ÙÙÙØ§ تصØÙØ Ø§ÙØ£Ø®Ø·Ø§Ø¡ - ÙØØµ اÙÙ
ØªØºÙØ±Ø§Øª ÙØªØªØ¨Ø¹ اÙÙÙØ¯ ÙÙ
Ø¹Ø±ÙØ© اÙÙ
ÙØ§Ù Ø§ÙØ°Ù ÙØ°Ùب ÙÙÙ Ø§ÙØªÙÙÙØ° بشÙ٠خاطئ.
+=======
+When paused, we can debug: examine variables and trace the code to see where the execution goes wrong.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ§Ù Ø§ÙØ¹Ø¯Ùد Ù
Ù Ø§ÙØ®Ùارات ÙÙ Ø£Ø¯ÙØ§Øª اÙÙ
Ø·ÙØ±ÙÙ Ø£ÙØ«Ø± Ù
٠تÙ٠اÙÙ
غطاة ÙÙØ§. Ø§ÙØ¯ÙÙ٠اÙÙØ§Ù
Ù ÙÙ .
diff --git a/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md b/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md
index 319b3933e..bf8e1c945 100644
--- a/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md
+++ b/1-js/03-code-quality/02-coding-style/1-style-errors/solution.md
@@ -2,6 +2,7 @@
ÙØ§ØØ¸ Ø§ÙØªØ§ÙÙ:
```js no-beautify
+<<<<<<< HEAD
function pow(x,n) // <- ÙØ§ Ù
Ø³Ø§ÙØ§Øª بÙ٠اÙÙ
Ø¹Ø·ÙØ§Øª
{ // <- اÙÙÙØ³ اÙÙ
عÙÙÙ Ù٠سطر Ø¬Ø¯ÙØ¯ ÙØØ¯Ù
let result=1; // <- ÙØ§ Ù
Ø³Ø§ÙØ© ÙØ¨Ù ا٠بعد =
@@ -15,6 +16,21 @@ let x=prompt("x?",''), n=prompt("n?",'') // <-- Ù
Ù
Ù٠تÙÙÙØ§,
if (n <= 0) // <- ÙØ§ Ù
Ø³Ø§ÙØ§Øª داخ٠(n <= 0), Ù ÙØ¬Ø¨ ا٠ÙÙÙÙ ÙÙØ§Ù٠سطر ÙÙÙÙ
{ // <- اÙÙÙØ³ اÙÙ
عÙÙÙ Ù٠سطر Ø¬Ø¯ÙØ¯ ÙØØ¯Ù
// Ø£Ø¯ÙØ§Ù - ÙÙ
ÙÙ ØªÙØ³ÙÙ
Ø§ÙØ®Ø·ÙØ· Ø§ÙØ·ÙÙÙØ© Ø¥ÙÙ Ø®Ø·ÙØ· Ù
تعددة ÙØªØØ³Ù٠اÙÙØ±Ø§Ø¡Ø©
+=======
+function pow(x,n) // <- no space between arguments
+{ // <- curly brace on a separate line
+ let result=1; // <- no spaces before or after =
+ for(let i=0;i>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
alert(`Power ${n} is not supported, please enter an integer number greater than zero`);
}
else // <- ÙÙ
Ù٠أ٠ÙÙØªØ¨ عÙ٠سطر ÙØ§ØØ¯ Ù
ث٠"} else {"
diff --git a/1-js/03-code-quality/02-coding-style/article.md b/1-js/03-code-quality/02-coding-style/article.md
index a497a57b0..a57c5832b 100644
--- a/1-js/03-code-quality/02-coding-style/article.md
+++ b/1-js/03-code-quality/02-coding-style/article.md
@@ -302,11 +302,19 @@ Linters ÙÙ Ø£Ø¯ÙØ§Øª ÙÙ
ÙÙÙØ§ Ø§ÙØªØÙ٠تÙÙØ§Ø¦ÙÙØ§ Ù
٠اسÙÙ
ÙÙÙ
ا ÙÙ٠بعض Ø£Ø¯ÙØ§Øª اÙÙØØµ Ø§ÙØ´ÙÙØ±Ø©:
+<<<<<<< HEAD
- [JSLint](http://www.jslint.com/) -- Ø£ØØ¯ Ø£ÙØ§Ø¦Ù Ø§Ø¯ÙØ§Øª اÙÙØØµ.
- [JSHint](http://www.jshint.com/) -- ب٠خصائص Ø§ÙØ«Ø± Ù
Ù JSLint.
- [ESLint](http://eslint.org/) -- ØºØ§ÙØ¨Ø§ ÙÙ Ø§ÙØ£ØØ¯Ø«.
ÙÙ
ÙÙ ÙØ¬Ù
ÙØ¹ÙÙ
اÙÙÙØ§Ù
Ø¨ÙØ°Ù اÙÙ
ÙÙ
Ø©. اÙÙ
ؤÙÙ ÙØ³ØªØ®Ø¯Ù
[ESLint](http://eslint.org/).
+=======
+- [JSLint](https://www.jslint.com/) -- one of the first linters.
+- [JSHint](https://jshint.com/) -- more settings than JSLint.
+- [ESLint](https://eslint.org/) -- probably the newest one.
+
+All of them can do the job. The author uses [ESLint](https://eslint.org/).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ØªØªÙØ§Ù
Ù Ù
عظÙ
Ø£Ø¯ÙØ§Øª ÙØØµ اÙÙÙØ¯ Ù
ع Ø§ÙØ¹Ø¯Ùد Ù
Ù Ù
ØØ±Ø±Ø§Øª Ø§ÙØ£ÙÙØ§Ø¯ Ø§ÙØ´ÙÙØ±Ø©: Ù
ا عÙÙ٠سÙ٠تÙ
ÙÙÙ Ø§ÙØ§Ø¶Ø§ÙØ© )(Plugin) Ù٠اÙÙ
ØØ±Ø± ÙØªÙÙÙ٠اÙÙÙØ¯.
@@ -336,7 +344,11 @@ Linters ÙÙ Ø£Ø¯ÙØ§Øª ÙÙ
ÙÙÙØ§ Ø§ÙØªØÙ٠تÙÙØ§Ø¦ÙÙØ§ Ù
٠اسÙÙ
ÙÙØ§ Ø§ÙØªÙجÙÙ `"extends"` ÙØ´Ùر Ø¥ÙÙ Ø£Ù Ø§ÙØªÙÙÙÙ ÙØ³ØªÙد Ø¥ÙÙ Ù
جÙ
ÙØ¹Ø© اعدادات "eslint:recommended" . بعد ذÙÙ ÙÙ
ÙÙÙØ§ ØªØØ¯Ùد Ø§ÙØ§Ø¹Ø¯Ø§Ø¯Ø§Øª Ø§ÙØ®Ø§ØµØ© Ø¨ÙØ§.
+<<<<<<< HEAD
Ù
٠اÙÙ
Ù
ÙÙ Ø£ÙØ¶Ùا ØªÙØ²ÙÙ Ù
جÙ
ÙØ¹Ø§Øª Ù
٠ارشادات Ø§ÙØ£Ø³ÙÙØ¨ Ù Ø§ÙØ§Ø¶Ø§ÙØ© عÙÙÙØ§ Ø¨Ø¯ÙØ§Ù Ù
٠ذÙÙ. See ÙÙ
عÙÙÙ
ات Ø£ÙØ«Ø± Ø¹Ù Ø§ÙØªÙزÙÙ.
+=======
+It is also possible to download style rule sets from the web and extend them instead. See for more details about installation.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
ا أ٠بعض Ø¨ÙØ¦Ø© تطÙÙØ± Ù
ØªÙØ§Ù
ÙØ© (IDEs) ØªØØªÙ٠عÙÙ Ø£Ø¯ÙØ§Øª ÙØØµ اÙÙÙØ¯ Ù
دÙ
Ø¬Ø©Ø ÙÙ٠أÙ
ر Ù
Ø±ÙØ ÙÙÙÙÙ ØºÙØ± ÙØ§Ø¨Ù ÙÙØªØ®ØµÙص Ù
ث٠ESLint.
diff --git a/1-js/03-code-quality/03-comments/article.md b/1-js/03-code-quality/03-comments/article.md
index dad7ef37d..5a312042d 100644
--- a/1-js/03-code-quality/03-comments/article.md
+++ b/1-js/03-code-quality/03-comments/article.md
@@ -145,7 +145,11 @@ function pow(x, n) {
باÙÙ
ÙØ§Ø³Ø¨Ø© Ø ÙÙ
ÙÙ ÙÙØ¹Ø¯Ùد Ù
٠اÙÙ
ØØ±Ø±ÙÙ Ù
ث٠[WebStorm] (https://www.jetbrains.com/webstorm/) ÙÙÙ
ÙÙ
Ø£ÙØ¶Ùا ÙØ§Ø³ØªØ®Ø¯Ø§Ù
ÙÙ
ÙØªÙÙÙØ± Ø§ÙØ¥ÙÙ
Ø§Ù Ø§ÙØªÙÙØ§Ø¦Ù ÙØ¨Ø¹Ø¶ Ø§ÙØªØÙÙ Ø§ÙØªÙÙØ§Ø¦Ù Ù
Ù Ø§ÙØªØ¹ÙÙÙ
ات Ø§ÙØ¨Ø±Ù
Ø¬ÙØ©.
+<<<<<<< HEAD
Ø£ÙØ¶Ùا Ø ÙÙØ§Ù Ø£Ø¯ÙØ§Øª Ù
ث٠[JSDoc 3] (https://github.com/jsdoc3/jsdoc) ÙÙ
ÙÙÙØ§ Ø¥ÙØ´Ø§Ø¡ ÙØ«Ø§Ø¦Ù HTML Ù
Ù Ø§ÙØªØ¹ÙÙÙØ§Øª. ÙÙ
ÙÙÙ ÙØ±Ø§Ø¡Ø© اÙÙ
Ø²ÙØ¯ Ù
٠اÙÙ
عÙÙÙ
ات ØÙÙ JSDoc عÙÙ .
+=======
+Also, there are tools like [JSDoc 3](https://github.com/jsdoc/jsdoc) that can generate HTML-documentation from the comments. You can read more information about JSDoc at .
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
اذا تØÙ اÙÙ
ÙÙ
Ø© Ø¨ÙØ°Ù Ø§ÙØ·Ø±ÙÙØ©Ø
: Ù
ا ÙÙ Ù
ÙØªÙب Ù
ÙÙ
. ÙÙÙ Ù
ا ÙÙ * ØºÙØ± * Ù
ÙØªÙب ÙØ¯ ÙÙÙÙ Ø£ÙØ«Ø± Ø£ÙÙ
ÙØ© ÙÙÙÙ
Ù
ا ÙØØ¯Ø«. ÙÙ
اذا ÙØªÙ
ØÙ اÙÙ
ÙÙ
Ø© Ø¨ÙØ°Ù Ø§ÙØ·Ø±ÙÙØ© Ø¨Ø§ÙØ¶Ø¨Ø·Ø اÙÙÙØ¯ ÙØ§ ÙØ¹Ø·Ù إجابة.
diff --git a/1-js/03-code-quality/05-testing-mocha/article.md b/1-js/03-code-quality/05-testing-mocha/article.md
index 7e0885492..a8617c357 100644
--- a/1-js/03-code-quality/05-testing-mocha/article.md
+++ b/1-js/03-code-quality/05-testing-mocha/article.md
@@ -2,7 +2,11 @@
ÙÙØ³ØªØ®Ø¯ÙÙ
Ø§ÙØ§Ø®ØªØ¨Ø§Ø± Ø§ÙØ¢ÙÙ Ù٠اÙÙØ«Ùر Ù
٠اÙÙ
ÙØ§Ù
Ø ÙÙ
ا ÙØ³ØªØ®Ø¯Ù
Ø¨ÙØ«Ø±Ø© Ù٠اÙÙ
Ø´Ø§Ø±ÙØ¹ Ø§ÙØÙÙÙÙØ©.
+<<<<<<< HEAD
## ÙÙ
ÙØØªØ§Ø¬ Ø§ÙØ§Ø®ØªØ¨Ø§Ø±Ø§ØªØ
+=======
+## Why do we need tests?
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¹ÙØ¯ ÙØªØ§Ø¨Ø© Ø¯Ø§ÙØ©Ø ÙÙ
ÙÙÙØ§ تخÙÙ Ù
ا ÙØ¬Ø¨ أ٠تÙÙÙ
بÙ: Ù
ا Ù٠اÙÙ
عاÙ
ÙØ§Øª Ø§ÙØªÙ ØªØ¹Ø·Ù ÙØªØ§Ø¦Ø¬ Ù
عÙÙØ©. ÙÙ
ÙÙÙØ§ ÙØØµ Ø§ÙØ¯Ø§ÙØ© Ø£Ø«ÙØ§Ø¡ Ø§ÙØªØ·ÙÙØ± Ù
Ù Ø®ÙØ§Ù تشغÙÙÙØ§ ÙÙ
ÙØ§Ø²ÙØ© Ù
Ø®Ø±Ø¬Ø§ØªÙØ§ Ù
ع Ù
ا ÙÙ Ù
تÙÙØ¹. Ù
Ø«ÙØ§ ÙÙ
ÙÙÙØ§ اÙÙÙØ§Ù
بذÙÙ ÙÙ Ø§ÙØ·Ø±ÙÙØ©.
@@ -53,7 +57,11 @@ describe("pow", function() {
ØªØØªÙ٠اÙÙ
ÙØ§ØµÙات عÙÙ 3 أجزاء Ø±Ø¦ÙØ³ÙØ© ÙÙ
ا تر٠ÙÙ Ø§ÙØ£Ø¹ÙÙ:
`describe("title", function() { ... })`
+<<<<<<< HEAD
: Ù
اÙ٠اÙÙØ¸ÙÙØ© Ø§ÙØªÙ ÙØµÙÙØ§Ø ÙÙ ÙØ°Ù Ø§ÙØØ§ÙØ©Ø ÙØÙ ÙØµÙ Ø§ÙØ¯Ø§ÙØ© pow. تستخدÙ
Ø¨ÙØ§Ø³Ø·Ø© Ø§ÙØ¹Ø§Ù
ÙÙÙ- أجزاء it.
+=======
+: What functionality we're describing? In our case we're describing the function `pow`. Used to group "workers" -- the `it` blocks.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
`it("use case description", function() { ... })`
: ÙØµÙ (ÙØÙ Ø¨Ø·Ø±ÙÙØ© Ù
ÙØ±Ùءة ÙÙØ¨Ø´Ø±) ØØ§ÙØ© Ø§ÙØ§Ø³ØªØ®Ø¯Ø§Ù
اÙÙ
خصصة Ù٠عÙÙØ§Ù itØ ÙØ§ÙÙ
عاÙ
Ù Ø§ÙØ¢Ø®Ø± عبارة Ø¹Ù Ø¯Ø§ÙØ© ØªÙØØµ ÙØ°Ù Ø§ÙØ¯Ø§ÙØ©.
@@ -69,6 +77,7 @@ describe("pow", function() {
ÙØ¨Ø¯Ù تدÙÙ Ø§ÙØªØ·ÙÙØ± ØºØ§ÙØ¨Ø§ ÙÙ
ا ÙÙÙ:
+<<<<<<< HEAD
1. ÙÙÙØªØ¨ اÙÙØµÙ Ø§ÙØ£ÙÙÙ Ù
ع ÙØØµ ÙÙÙØ¸ÙÙØ© Ø§ÙØ±Ø¦ÙØ³ÙØ©.
2. ÙÙÙØ´Ùئ تÙÙÙØ° Ø£ÙÙÙ.
3. ÙØªØ£Ùد Ù
Ù ØµØØ© عÙ
Ù Ø§ÙØªÙÙÙØ°Ø ÙÙØ´ÙغÙÙ٠إطار Ø§ÙØªÙÙÙÙ
[Mocha](http://mochajs.org/) Ø§ÙØ°Ù ÙÙØ´ÙغÙÙ٠اÙÙØµÙ. Ø³ØªØ¸ÙØ± أخطاء ÙÙ ØØ§Ù عدÙ
Ø§ÙØªÙ
ا٠اÙÙØ¸Ø§Ø¦Ù. ÙÙØµØØ Ø§ÙØ£Ø®Ø·Ø§Ø¡ ØØªÙ ÙØµØ¨Ø ÙÙ Ø´ÙØ¡ صØÙØÙا.
@@ -76,20 +85,39 @@ describe("pow", function() {
5. ÙØ¶Ù٠اÙÙ
Ø²ÙØ¯ Ù
Ù ØØ§Ùات Ø§ÙØ§Ø³ØªØ®Ø¯Ø§Ù
ÙÙÙØµÙØ Ø±Ø¨Ù
ا بعض ÙØ°Ù اÙÙ
ÙØ²Ø§Øª ÙÙØ³ Ù
ضÙ
ÙØ§ ÙÙ Ø§ÙØªÙÙÙØ° بعد. ØÙÙÙØ§ ÙØ¨Ø¯Ø£ Ø§ÙØ§Ø®ØªØ¨Ø§Ø± باÙÙØ´Ù.
6. Ø¹ÙØ¯ ÙÙØ®Ø·ÙØ© 3 ÙØØ¯ÙÙØ« Ø§ÙØªÙÙÙØ° Ø¥Ù٠أ٠تختÙÙ ÙÙ Ø§ÙØ£Ø®Ø·Ø§Ø¡.
7. ÙØ±Ø± Ø§ÙØ®Ø·Ùات 3-6 ØØªÙ ØªØ¬ÙØ² Ù٠اÙÙØ¸Ø§Ø¦Ù.
+=======
+1. An initial spec is written, with tests for the most basic functionality.
+2. An initial implementation is created.
+3. To check whether it works, we run the testing framework [Mocha](https://mochajs.org/) (more details soon) that runs the spec. While the functionality is not complete, errors are displayed. We make corrections until everything works.
+4. Now we have a working initial implementation with tests.
+5. We add more use cases to the spec, probably not yet supported by the implementations. Tests start to fail.
+6. Go to 3, update the implementation till tests give no errors.
+7. Repeat steps 3-6 till the functionality is ready.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¥Ø°Ø§Ø ØªÙØ¹Ø¯ عÙ
ÙÙØ© Ø§ÙØªØ·ÙÙØ± ØªÙØ±Ø§Ø±ÙØ©. ÙÙØªØ¨ اÙÙØµÙØ ÙÙÙØ°ÙØ ÙØªØ£Ùد Ù
Ù Ø§Ø¬ØªÙØ§Ø² Ø§ÙØªÙÙÙØ° ÙÙÙØØµØ Ø«Ù
ÙÙØªØ¨ اÙÙ
Ø²ÙØ¯ Ù
Ù Ø§ÙØ§Ø®ØªØ¨Ø§Ø±Ø§ØªØ ÙØªØ£Ùد Ù
Ù ØµØØ© عÙ
ÙÙØ§. ØØªÙ ÙØØµÙ Ø¹Ù٠تÙÙÙØ° صØÙØ Ù
ع اختبارات٠ÙÙ Ø§ÙØ£Ø®Ùر.
ÙÙÙØ¬Ø±Ø¨ تدÙÙ Ø§ÙØªØ·ÙÙØ± ÙØ°Ø§ عÙÙ ØØ§ÙØªÙØ§ Ø§ÙØ¹Ù
ÙÙØ©.
+<<<<<<< HEAD
Ø§ÙØ®Ø·ÙØ© 1 Ø£ØµØ¨ØØª Ø¬Ø§ÙØ²Ø©: ÙØ¯ÙÙØ§ ÙØµÙÙØ§ Ù
بدئÙÙÙØ§ ÙÙØ¯Ø§ÙØ© `pow`. Ø§ÙØ¢Ù ÙÙØ¨Ù Ø§ÙØªÙÙÙØ°Ø ÙÙÙØ³ØªØ®Ø¯Ù
بعض Ù
ÙØ§ØªØ¨ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØªØ´ØºÙÙ Ø§ÙØ§Ø®ØªØ¨Ø§Ø± ØØªÙ ÙØªØ£Ùد Ù
Ù Ø¥Ù ÙØ§Ùت تعÙ
Ù (Ù٠تعÙ
Ù).
+=======
+The first step is already complete: we have an initial spec for `pow`. Now, before making the implementation, let's use a few JavaScript libraries to run the tests, just to see that they are working (they will all fail).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## اÙÙ
ÙØ§ØµÙات Ø£Ø«ÙØ§Ø¡ Ø§ÙØªÙÙÙØ°
Ø³ÙØ³ØªØ®Ø¯Ù
ÙÙ ÙØ°Ø§ Ø§ÙØ´Ø±Ø Ù
ÙØ§ØªØ¨ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت Ø§ÙØªØ§ÙÙØ© ÙÙØ§Ø®ØªØ¨Ø§Ø±:
+<<<<<<< HEAD
- [Mocha](http://mochajs.org/) -- ÙØ¥Ø·Ø§Ø± Ø§ÙØ±Ø¦ÙسÙ: ÙÙÙØ± Ø¯ÙØ§Ù اÙÙØØµ Ø§ÙØ£Ùثر استخداÙ
ÙØ§ Ù
ا ÙØ´Ù
Ù describe Ù it Ø¨Ø§ÙØ¥Ø¶Ø§ÙØ© Ø¥ÙÙ Ø§ÙØ¯ÙØ§Ù Ø§ÙØ±Ø¦ÙØ³ÙØ© Ø§ÙØªÙ ØªÙØ´ÙغÙÙÙ Ø§ÙØ§Ø®ØªØ¨Ø§Ø±.
- [Chai](http://chaijs.com) -- ÙÙ
ÙØªØ¨Ø© اÙÙ
ØØªÙÙØ© عÙÙ Ø¯ÙØ§Ù تأÙÙØ¯ÙØ©. ØªØªÙØ ÙÙØ§ استخداÙ
Ø§ÙØ¹Ø¯Ùد Ù
Ù ÙØ°Ù Ø§ÙØ¯ÙØ§ÙØ ÙØØªØ§Ø¬ Ø§ÙØ¢Ù `assert.equal` ÙÙØ·. .
- [Sinon](http://sinonjs.org/) -- a Ù
ÙØªØ¨Ø© ÙÙØªØ¬Ø³Ø³ عÙÙ Ø§ÙØ¯ÙØ§ÙØ ÙÙ
ØØ§Ùاة Ø§ÙØ¯Ùا٠اÙÙ
دÙ
Ø¬Ø©Ø ÙØ§ÙÙ
Ø²ÙØ¯Ø Ø³ÙØØªØ§Ø¬ ÙØ°Ù اÙÙ
ÙØªØ¨Ø© ÙØ§ØÙا.
+=======
+- [Mocha](https://mochajs.org/) -- the core framework: it provides common testing functions including `describe` and `it` and the main function that runs tests.
+- [Chai](https://www.chaijs.com/) -- the library with many assertions. It allows to use a lot of different assertions, for now we need only `assert.equal`.
+- [Sinon](https://sinonjs.org/) -- a library to spy over functions, emulate built-in functions and more, we'll need it much later.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ØªÙØ¹Ø¯ ÙØ°Ù اÙÙ
ÙØ§ØªØ¨ Ù
ÙÙØ¯Ø© ÙÙØ§Ø®ØªØ¨Ø§Ø± ÙÙ ÙÙ Ù
٠اÙÙ
ØªØµÙØ ÙØ§ÙخادÙ
. Ø³ÙØ£Ø®Ø° بعÙÙ Ø§ÙØ§Ø¹ØªØ¨Ø§Ø± ÙÙØ§ Ø¬ÙØ© اÙÙ
ØªØµÙØ. ØµÙØØ© HTML ÙØ§Ù
ÙØ© Ù
ع ÙØ°Ù اÙÙ
ÙØ§ØªØ¨ ÙÙØµÙ Ø§ÙØ¯Ø§ÙØ© pow:
@@ -325,6 +353,7 @@ describe("pow", function() {
ØªÙØ´Ù Ø§ÙØ§Ø®ØªØ¨Ø§Ø±Ø§Øª اÙÙ
ÙØ¶Ø§ÙØ© Ù
ؤخرا ÙØ°ÙÙ ÙØ£Ù Ø§ÙØªÙÙÙØ° ÙØ§ ÙØ¯Ø¹Ù
ÙØ§. ÙÙØ°Ø§ ÙÙ Ø§ÙØ·Ø±ÙÙØ© Ø§ÙØªÙ ÙØ¹Ù
Ù Ø¨ÙØ§ BDD: ÙØ¨Ø¯Ø£ Ø¨ÙØªØ§Ø¨Ø© Ø§ÙØ§Ø®ØªØ¨Ø§Ø±Ø§Øª Ø§ÙØªÙ ÙØ¹ÙÙ
بأÙÙØ§ Ø³ØªÙØ´Ù Ø«Ù
ÙÙØªØ¨ Ø§ÙØªÙÙÙØ° Ø§ÙØ®Ø§Øµ Ø¨ÙØ§.
+<<<<<<< HEAD
```smart header="Ø¯ÙØ§Ù تأÙÙØ¯ أخرÙ"
ÙØ§ØØ¸ Ø£Ù Ø§ÙØ¯Ø§ÙØ© assert.isNaN: ØªÙØØµ ÙØ¬Ùد اÙÙÙÙ
Ø© NaN.
@@ -342,6 +371,16 @@ describe("pow", function() {
- `assert.isTrue(value)` -- ØªÙØØµ Ø£Ù value === true.
- `assert.isFalse(value)` -- ØªÙØØµ Ø£Ù value === false.
- ...ÙÙ
ÙÙÙ ÙØ±Ø§Ø¡Ø© باÙÙ Ø§ÙØ¯Ùا٠ÙÙ [docs](http://chaijs.com/api/assert/)
+=======
+There are other assertions in [Chai](https://www.chaijs.com/) as well, for instance:
+
+- `assert.equal(value1, value2)` -- checks the equality `value1 == value2`.
+- `assert.strictEqual(value1, value2)` -- checks the strict equality `value1 === value2`.
+- `assert.notEqual`, `assert.notStrictEqual` -- inverse checks to the ones above.
+- `assert.isTrue(value)` -- checks that `value === true`
+- `assert.isFalse(value)` -- checks that `value === false`
+- ...the full list is in the [docs](https://www.chaijs.com/api/assert/)
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
ÙØ°Ø§Ø ÙØ¬Ø¨ Ø£Ù ÙØ¶Ù٠بعض Ø§ÙØ£Ø³Ø·Ø± ÙÙØ¯Ø§ÙØ© pow:
diff --git a/1-js/03-code-quality/06-polyfills/article.md b/1-js/03-code-quality/06-polyfills/article.md
index 40f7c2520..fadbbfd09 100644
--- a/1-js/03-code-quality/06-polyfills/article.md
+++ b/1-js/03-code-quality/06-polyfills/article.md
@@ -2,13 +2,23 @@
# Ø§ÙØ¨ÙÙÙÙÙÙØ² ÙØ§ÙÙ
ترجÙ
ات
+<<<<<<< HEAD
اÙÙØ±Ù Ø®ÙÙ Ù
ØØ±Ùات Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØ¯ÙÙÙ
اÙÙØ§Ø±ÙÙ
Ø§ÙØ®Ø§ØµÙ ع٠Ù
اذا ÙÙÙÙ
ÙØ§ بتÙÙÙØ°Ù اÙÙØ§Ù. ÙØ¯ ÙÙØ±Ø±Ù٠تÙÙÙØ° اÙÙ
ÙØªØ±ØØ§Øª اÙÙ
ÙØ¬Ùدة Ù٠اÙÙ
Ø³ÙØ¯Ø© ÙØªØ£Ø¬ÙÙ Ø§ÙØ£Ø´Ùاء اÙÙ
ÙØ¬Ùدة باÙÙØ¹Ù Ù٠اÙÙ
ÙØ§ØµÙات, ÙØ£ÙÙÙ
Ø£Ù٠إثارة ÙÙØ§ÙتÙ
اÙ
Ø£Ù ÙØµØ¹Ø¨ اÙÙÙØ§Ù
بÙÙ
.
+=======
+The JavaScript language steadily evolves. New proposals to the language appear regularly, they are analyzed and, if considered worthy, are appended to the list at and then progress to the [specification](https://www.ecma-international.org/publications-and-standards/standards/ecma-262/).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ°Ø§ ÙÙ
Ù Ø§ÙØ´Ø§Ø¦Ø¹ تÙ
اÙ
ÙØ§ Ø£Ù ÙÙÙÙ
اÙÙ
ØØ±Ù بتطبÙÙ Ø§ÙØ¬Ø²Ø¡ اÙÙÙØ§Ø³Ù ÙÙØ·.
+<<<<<<< HEAD
ØµÙØØ© Ø¬ÙØ¯Ø© ÙÙ
Ø¹Ø±ÙØ© Ø§ÙØØ§ÙØ© Ø§ÙØØ§ÙÙØ© ÙØ¯Ø¹Ù
Ù
ÙØ²Ø§Øª اÙÙØºØ© ÙÙ (Ø¥ÙÙØ§ ضخÙ
Ù, ÙØ¯ÙÙØ§ اÙÙØ«Ùر ÙÙØ¯Ø±Ø³Ù بعد).
ÙÙ
برÙ
جÙÙØ ÙÙØ¯ استخداÙ
اÙÙ
ÙØ²Ø§Øª Ø§ÙØ£ØØ¯Ø«. ÙÙÙ
ا ÙØ§Ù ÙÙØ§Ù اÙÙ
Ø²ÙØ¯ Ù
٠اÙÙ
ÙØ²Ø§Øª Ø§ÙØ¬Ùدة - ÙÙÙ
ا ÙØ§Ù Ø£ÙØ¶Ù!
+=======
+So it's quite common for an engine to implement only part of the standard.
+
+A good page to see the current state of support for language features is (it's big, we have a lot to study yet).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù
Ù ÙØ§ØÙØ© Ø£Ø®Ø±ÙØ ÙÙÙ ÙÙ
ÙÙÙØ§ Ø¬Ø¹Ù Ø´ÙØ±ØªÙا Ø§ÙØØ¯ÙØ«Ø© تعÙ
٠عÙÙ Ù
ØØ±Ùات Ø£ÙØ¯Ù
ÙØ§ تÙÙÙ
اÙÙ
ÙØ²Ø§Øª Ø§ÙØØ¯ÙØ«Ø© بعدØ
@@ -23,7 +33,11 @@
اÙÙ
ØÙÙ٠اÙÙØºÙÙ (Transpiler) ÙÙ Ø¨Ø±ÙØ§Ù
ج خاص ÙÙ
ÙÙ٠تØÙÙÙ Ø§ÙØ´Ùرة Ø§ÙØØ¯ÙØ«Ø© ÙØ¥Ø¹Ø§Ø¯Ø© ÙØªØ§Ø¨ØªÙا باستخداÙ
بÙÙ Ø¨ÙØ§Ø¡ ÙØºÙÙØ© Ø£ÙØ¯Ù
Ø Ø¨ØÙØ« ÙØªÙ
Ø§ÙØØµÙ٠عÙÙ ÙÙØ³ اÙÙØªÙجة.
+<<<<<<< HEAD
عÙ٠سبÙ٠اÙÙ
Ø«Ø§ÙØ ÙØ§Ù ÙØºØ© JavaScript ÙØ¨Ù عاÙ
2020 ÙØ§ تتضÙ
Ù "عاÙ
٠تجÙ
ÙØ¹ اÙÙÙÙ
اÙÙØ§Ø±ØºØ© Nullish Coalescing" `??`. ÙØ°ÙÙØ إذا استخدÙ
Ø§ÙØ²Ø§Ø¦Ø± Ù
ØªØµÙØ ÙØ¯ÙÙ
Ø ÙÙØ¯ ÙÙØ´Ù ÙÙ ÙÙÙ
Ø§ÙØ´Ùرة Ù
ث٠`height = height ?? 100`.
+=======
+A [transpiler](https://en.wikipedia.org/wiki/Source-to-source_compiler) is a special piece of software that translates source code to another source code. It can parse ("read and understand") modern code and rewrite it using older syntax constructs, so that it'll also work in outdated engines.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ ÙØ°Ù Ø§ÙØØ§ÙØ©Ø ÙÙÙÙ
اÙÙ
ØÙÙ٠اÙÙØºÙ٠بتØÙÙÙ Ø§ÙØ´Ùرة ÙØ¥Ø¹Ø§Ø¯Ø© ÙØªØ§Ø¨Ø© `height ?? 100` Ø¥ÙÙ `(height !== undefined && height !== null) ? height : 100`.
@@ -39,15 +53,25 @@ height = (height !== undefined && height !== null) ? height : 100;
Ø¹Ø§Ø¯Ø©ÙØ ÙÙÙÙ
اÙÙ
Ø·ÙÙØ± بتشغÙ٠اÙÙ
ØÙÙ٠اÙÙØºÙ٠عÙÙ Ø¬ÙØ§Ø²Ù Ø§ÙØ®Ø§ØµØ Ø«Ù
ÙÙØ´Ø± Ø§ÙØ´Ùرة اÙÙ
ØÙÙÙØ© عÙÙ Ø§ÙØ®Ø§Ø¯Ù
.
+<<<<<<< HEAD
ÙØ¨Ø§ÙÙØ³Ø¨Ø© ÙÙØ§Ø³Ù
Ø ÙØ¥Ù [Babel](https://babeljs.io) ÙÙ Ø£ØØ¯ Ø£Ø´ÙØ± اÙÙ
ØÙÙÙØ§Øª اÙÙØºÙÙØ© اÙÙ
ØªØ§ØØ©.
تÙÙØ± Ø£ÙØ¸Ù
Ø© Ø¨ÙØ§Ø¡ اÙÙ
Ø´Ø§Ø±ÙØ¹ Ø§ÙØØ¯ÙØ«Ø©Ø Ù
ث٠[webpack](http://webpack.github.io/)Ø ÙØ³Ø§Ø¦Ù ÙØªØ´ØºÙ٠اÙÙ
ØÙÙ٠اÙÙØºÙ٠تÙÙØ§Ø¦ÙÙØ§ Ø¹ÙØ¯ Ù٠تغÙÙØ± ÙÙ Ø§ÙØ´ÙØ±Ø©Ø ÙØ°ÙÙ ÙÙ
Ù Ø§ÙØ³ÙÙ Ø¬Ø¯ÙØ§ دÙ
ج٠Ù٠عÙ
ÙÙØ© Ø§ÙØªØ·ÙÙØ±.
+=======
+Speaking of names, [Babel](https://babeljs.io) is one of the most prominent transpilers out there.
+
+Modern project build systems, such as [webpack](https://webpack.js.org/), provide a means to run a transpiler automatically on every code change, so it's very easy to integrate into the development process.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## Ø§ÙØ¨ÙÙÙÙÙÙØ²
ÙØ¯ تشÙ
٠اÙÙ
ÙØ²Ø§Øª اÙÙØºÙÙØ© Ø§ÙØ¬Ø¯Ùدة ÙØºØ© Ø§ÙØ¨Ø±Ù
جةÙÙØ³Øª Ù
جرد بÙÙ Ø¨ÙØ§Ø¡ ÙØºÙÙØ© ÙØ¹ÙاÙ
٠تجÙ
ÙØ¹Ø ب٠ÙÙ
ÙÙ Ø£ÙØ¶Ùا أ٠تشÙ
Ù ÙØ¸Ø§Ø¦Ù Ù
دÙ
جة.
+<<<<<<< HEAD
عÙ٠سبÙ٠اÙÙ
Ø«Ø§ÙØ تعتبر `Math.trunc(n)` ÙØ¸ÙÙØ© تÙÙÙ
ب٠"ÙØµ" Ø§ÙØ¬Ø²Ø¡ Ø§ÙØ¹Ø´Ø±Ù Ù
٠رÙÙ
Ø Ø¹Ù٠سبÙ٠اÙÙ
ثا٠`Math.trunc(1.23) = 1`.
+=======
+For example, `Math.trunc(n)` is a function that "cuts off" the decimal part of a number, e.g `Math.trunc(1.23)` returns `1`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù٠بعض Ù
ØØ±Ùات JavaScript اÙÙØ¯ÙÙ
Ø© Ø¬Ø¯ÙØ§Ø ÙØ§ ÙÙØ¬Ø¯ `Math.trunc`Ø ÙØ°ÙÙ Ø³ØªÙØ´Ù ÙØ°Ù Ø§ÙØ´Ùرة.
@@ -68,17 +92,23 @@ if (!Math.trunc) { // إذا ÙÙ
ÙÙØ¬Ø¯ ÙØ°Ù اÙÙØ¸ÙÙØ©
}
```
+<<<<<<< HEAD
JavaScript ÙÙ ÙØºØ© دÙÙØ§Ù
ÙÙÙØ© بشÙÙ ÙØ¨ÙØ±Ø ØÙØ« ÙÙ
ÙÙ ÙÙÙØµÙص Ø§ÙØ¨Ø±Ù
Ø¬ÙØ© Ø¥Ø¶Ø§ÙØ©/تعدÙÙ Ø£Ù ÙØ¸Ø§Ø¦ÙØ Ø¨Ù
ا Ù٠ذÙ٠تÙ٠اÙÙ
دÙ
جة Ù٠اÙÙØºØ©.
ÙÙØ§Ù Ù
ÙØªØ¨ØªØ§Ù Ø¬Ø¯ÙØ±ØªØ§Ù Ø¨Ø§ÙØ§ÙتÙ
اÙ
Ù
٠بÙÙ Ù
ÙØªØ¨Ø§Øª Polyfills:
- [core-js](https://github.com/zloirock/core-js) Ø§ÙØªÙ تدعÙ
Ø§ÙØ¹Ø¯Ùد Ù
٠اÙÙ
ÙØ²Ø§ØªØ ÙØªØ³Ù
Ø Ø¨ØªØ¶Ù
Ù٠اÙÙ
ÙØ²Ø§Øª اÙÙ
Ø·ÙÙØ¨Ø© ÙÙØ·.
- خدÙ
Ø© [polyfill.io](http://polyfill.io) Ø§ÙØªÙ تÙÙØ± Ø¨Ø±ÙØ§Ù
Ø¬ÙØ§ ÙØµÙÙÙÙØ§ Ù
ع PolyfillsØ ÙØ¹ØªÙ
د عÙ٠اÙÙ
ÙØ²Ø§Øª ÙÙ
ØªØµÙØ اÙÙ
ستخدÙ
.
+=======
+JavaScript is a highly dynamic language. Scripts may add/modify any function, even built-in ones.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
+One interesting polyfill library is [core-js](https://github.com/zloirock/core-js), which supports a wide range of features and allows you to include only the ones you need.
## اÙÙ
ÙØ®Øµ
ÙÙ ÙØ°Ø§ اÙÙØµÙØ ÙÙØ¯ تØÙÙØ²Ù عÙ٠دراسة Ù
ÙØ²Ø§Øª اÙÙØºØ© Ø§ÙØØ¯ÙØ«Ø© ÙØØªÙ "Ø§ÙØØ§ÙØ© Ø§ÙØØ§Ø¯Ø©"Ø ØØªÙ ÙÙ ÙÙ
ÙØªÙ
دعÙ
ÙØ§ بشÙÙ Ø¬ÙØ¯ Ø¨ÙØ§Ø³Ø·Ø© Ù
ØØ±Ùات JavaScript.
+<<<<<<< HEAD
ÙÙÙÙ ÙØ§ ØªÙØ³Ù استخداÙ
اÙÙ
ترجÙ
(إذا استخدÙ
ت بÙÙØ© عبارات أ٠عÙ
ÙÙØ§Øª ØØ¯Ùثة) ÙØ§ÙبÙÙÙÙÙÙØ² (ÙØ¥Ø¶Ø§ÙØ© اÙÙØ¸Ø§Ø¦Ù Ø§ÙØªÙ ÙØ¯ ØªÙØªÙر Ø¥ÙÙÙØ§). ÙØ³ÙضÙ
ÙÙÙ Ø£Ù ÙØ¹Ù
٠اÙÙÙØ¯.
عÙ٠سبÙ٠اÙÙ
Ø«Ø§ÙØ Ø¹ÙØ¯Ù
ا ØªØµØ¨Ø Ù
ØªØ¹ÙØ¯Ùا عÙÙ JavaScriptØ ÙÙ
ÙÙ٠إعداد ÙØ¸Ø§Ù
Ø¨ÙØ§Ø¡ Ø§ÙØ´Ùرة عÙ٠أساس [webpack](http://webpack.github.io/) Ù
ع Ù
ÙØÙ [babel-loader](https://github.com/babel/babel-loader).
@@ -86,6 +116,15 @@ JavaScript ÙÙ ÙØºØ© دÙÙØ§Ù
ÙÙÙØ© بشÙÙ ÙØ¨ÙØ±Ø ØÙØ« ÙÙ
ÙÙ Ù
ÙÙØ§Ù Ù
ÙØ§Ø±Ø¯ Ø¬ÙØ¯Ø© ØªÙØ¶Ø Ø§ÙØØ§ÙØ© Ø§ÙØØ§ÙÙØ© ÙØ¯Ø¹Ù
Ø§ÙØ¹Ø¯Ùد Ù
٠اÙÙ
ÙØ²Ø§ØªØ ÙÙÙ:
- - ÙÙØ¬Ø§ÙØ§Ø³ÙØ±Ùبت Ø§ÙØ®Ø§Ù
.
- - ÙÙØ¸Ø§Ø¦Ù اÙÙ
ØªØµÙØ.
+=======
+Just don't forget to use a transpiler (if using modern syntax or operators) and polyfills (to add functions that may be missing). They'll ensure that the code works.
+
+For example, later when you're familiar with JavaScript, you can setup a code build system based on [webpack](https://webpack.js.org/) with the [babel-loader](https://github.com/babel/babel-loader) plugin.
+
+Good resources that show the current state of support for various features:
+- - for pure JavaScript.
+- - for browser-related functions.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
٠اÙÙ
عرÙÙ Ø£Ù Ø¬ÙØ¬Ù ÙØ±ÙÙ
ÙÙ Ø§ÙØ£Ùثر ØªØØ¯ÙØ«ÙØ§ باÙÙØ³Ø¨Ø© ÙÙ
ÙØ²Ø§Øª اÙÙØºØ©Ø جرب استخداÙ
٠إذا ÙØ´Ù تطبÙ٠تعÙÙÙ
Ù. ÙÙ
ع ذÙÙØ ÙØ¹Ù
Ù Ù
عظÙ
تطبÙÙØ§Øª Ø§ÙØªØ¹ÙÙÙ
ات Ø§ÙØ¨Ø±Ù
Ø¬ÙØ© Ù
ع Ø£Ù Ù
ØªØµÙØ ØØ¯ÙØ«.
diff --git a/1-js/04-object-basics/01-object/article.md b/1-js/04-object-basics/01-object/article.md
index 2834171ad..f9de5ff33 100644
--- a/1-js/04-object-basics/01-object/article.md
+++ b/1-js/04-object-basics/01-object/article.md
@@ -5,7 +5,11 @@
Ù٠اÙÙ
ÙØ§Ø¨ÙØ ØªØ³ØªØ®Ø¯Ù
اÙÙØ§Ø¦Ùات ÙØÙØ¸ Ù
جÙ
ÙØ¹Ø§Øª keyed collections Ù
Ù Ù
ختÙÙ Ø§ÙØ¨ÙØ§ÙØ§Øª ÙØ§ÙÙÙØ§Ùات اÙÙ
Ø±ÙØ¨Ø©.ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±ÙØ¨ØªØ ØªØ¯Ø®Ù Ø§ÙÙØ§Ø¦Ùات ØªÙØ±Ùبا ÙÙ ÙÙ Ø¬Ø§ÙØ¨ Ù
Ù Ø¬ÙØ§Ùب اÙÙØºØ©. ÙØ°Ø§ ÙØªÙجب عÙÙÙØ§ ÙÙÙ
ÙØ§ ÙØ¨Ù Ø§ÙØªØ¹Ù
Ù ÙÙ Ø£Ù Ø´ÙØ¡ آخر.
+<<<<<<< HEAD
ÙÙ
ÙÙ Ø¥ÙØ´Ø§Ø¡ Ø£Ù ÙØ§Ø¦Ù باستخداÙ
Ø§ÙØ£ÙÙØ§Ø³ اÙÙ
عÙÙÙØ© `{â¦}` Ù
ع ÙØ§Ø¦Ù
Ø© Ø§Ø®ØªÙØ§Ø±ÙØ© Ø¨Ø§ÙØ®Ø§ØµÙات. Ø§ÙØ®Ø§ØµÙØ© ÙÙ Ø²ÙØ¬ Ù
Ù "Ù
ÙØªØ§Ø: ÙÙÙ
Ø©" (`key: value`) إذ ÙÙÙ٠اÙÙ
ÙØªØ§Ø عبارة Ø¹Ù ÙØµ (ÙÙØ¯Ø¹Ù "اسÙ
Ø§ÙØ®Ø§ØµÙØ©")Ø ÙØ§ÙÙÙÙ
Ø© ÙÙ
Ù٠أ٠تÙÙÙ Ø£Ù Ø´ÙØ¡.
+=======
+An object can be created with curly braces `{â¦}` with an optional list of *properties*. A property is a "key: value" pair, where `key` is a string (also called a "property name"), and `value` can be anything.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
ÙÙÙØ§ تخÙ٠اÙÙØ§Ø¦Ù ÙØ®Ø²Ø§ÙØ© تØÙÙ Ù
ÙÙØ§Øª. ÙÙØ®Ø²Ù Ù٠جزء Ù
Ù ÙØ°Ù Ø§ÙØ¨ÙØ§ÙØ§Øª Ù٠اÙÙ
ÙÙ Ø§ÙØ®Ø§Øµ ب٠باستخداÙ
اÙÙ
ÙØªØ§Ø. ÙÙ
ÙÙ Ø¥ÙØ¬Ø§Ø¯Ø Ø£Ù Ø¥Ø¶Ø§ÙØ©Ø Ø£Ù ØØ°Ù Ù
Ù٠باستخداÙ
اسÙ
Ù.
@@ -20,7 +24,11 @@ let user = {}; // "object literal" syntax

+<<<<<<< HEAD
ØªÙØ³ØªØ®Ø¯Ù
Ø§ÙØ£ÙÙØ§Ø³ اÙÙ
عÙÙÙØ© `{...}` Ø¹Ø§Ø¯Ø©Ø ÙÙØ°Ø§ اÙÙÙØ¹ Ù
Ù Ø§ÙØªØµØ±ÙØ ÙÙØ³Ù
٠«*Ø§ÙØµÙاغة اÙÙ
ختصرة ÙØªØ¹Ø±ÙÙ ÙØ§Ø¦Ù*» (*object literal*).
+=======
+Usually, the curly braces `{...}` are used. That declaration is called an *object literal*.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## اÙÙÙÙ
اÙÙ
ÙØ¬Ø±ÙÙØ¯Ø© ÙØ§ÙØ®Ø§ØµÙØ§Øª
@@ -44,7 +52,11 @@ let user = { // an object ÙØ§Ø¦Ù

+<<<<<<< HEAD
ÙÙ
ÙÙÙØ§ Ø¥Ø¶Ø§ÙØ©Ø ÙØØ°ÙØ ÙÙØ±Ø§Ø¡Ø© اÙÙ
ÙÙØ§Øª Ù
Ù Ø§ÙØ®Ø²Ø§ÙØ© Ù٠أ٠ÙÙØª.
+=======
+We can add, remove and read files from it at any time.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
Ù٠اÙÙØµÙ٠إÙÙ ÙÙÙ
Ø§ÙØ®Ø§ØµÙات باستخداÙ
Ø§ÙØµÙغة اÙÙÙÙÙØ·ÙØ© (dot notation):
@@ -62,7 +74,11 @@ user.isAdmin = true;

+<<<<<<< HEAD
ÙÙ
ÙÙÙØ§ استخداÙ
اÙÙ
ÙØ¹Ø§Ù
ÙÙ `delete` ÙØØ°Ù Ø®Ø§ØµÙØ©:
+=======
+To remove a property, we can use the `delete` operator:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
delete user.age;
@@ -225,13 +241,21 @@ let bag = {
};
```
+<<<<<<< HEAD
Ø§ÙØ£ÙÙØ§Ø³ اÙÙ
ربعة Ø£ÙÙÙ Ø¨ÙØ«Ùر Ù
٠استخداÙ
Ø§ÙØµÙغة اÙÙÙÙØ·ÙØ©. ØÙØ« تسÙ
Ø Ø¨Ø§Ø³ØªØ®Ø¯Ø§Ù
أ٠أسÙ
اء خصائص ÙÙ
ØªØºÙØ±Ø§Øª. ÙÙÙÙØ§ Ø£ÙØ¶Ø§ Ø£ÙØ«Ø± Ø¥Ø±ÙØ§Ùا٠Ù٠اÙÙØªØ§Ø¨Ø©.
+=======
+Square brackets are much more powerful than dot notation. They allow any property names and variables. But they are also more cumbersome to write.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ°ÙÙØ Ù
عظÙ
اÙÙÙØªØ ØÙÙÙ
ا ÙÙÙ٠اسÙ
Ø®Ø§ØµÙØ© Ù
عرÙÙØ§ Ø£Ù ØºÙØ± Ù
Ø±ÙØ¨Ø تستخدÙ
Ø§ÙØµÙغة اÙÙÙÙØ·ÙØ©. ÙØ¥Ø°Ø§ Ø£Ø±Ø¯ÙØ§ Ø´ÙØ¦Ø§Ù Ø£ÙØ«Ø± تعÙÙØ¯Ø§Ø ÙÙØªÙ٠إÙ٠استخداÙ
Ø§ÙØ£ÙÙØ§Ø³ اÙÙ
ربعة.
## اختصار ÙÙÙ
Ø© Ø§ÙØ®Ø§ØµÙØ© (Property value shorthand)
+<<<<<<< HEAD
ÙÙ Ø§ÙØ´ÙÙØ±Ø© Ø§ÙØÙÙÙÙØ©Ø ØºØ§ÙØ¨Ùا Ù
ا ÙØ³ØªØ®Ø¯Ù
اÙÙ
ØªØºÙØ±Ø§Øª اÙÙ
ÙØ¬Ùدة Ø¨ØµÙØªÙا ÙÙÙÙ
ÙØ§ ÙØ£Ø³Ù
اء Ø§ÙØ®ØµØ§Ø¦Øµ.
+=======
+In real code, we often use existing variables as values for property names.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù
Ø«ÙØ§Ù:
@@ -276,7 +300,11 @@ let user = {
## ÙÙÙØ¯ أسÙ
اء Ø§ÙØ®ØµØ§Ø¦Øµ Property names limitations
+<<<<<<< HEAD
ÙÙ
ا ÙØ¹ÙÙ
Ø ÙØ§ ÙÙ
ÙÙ ÙÙÙ
ØªØºÙØ± Ø£Ù ÙÙ
تÙ٠اسÙ
Ø§Ù ÙØ³Ø§ÙÙ ÙØ§ØØ¯Ø§Ù Ù
٠اÙÙÙÙ
ات اÙÙ
ØÙÙØ¸Ø© ÙÙØºØ© (language-reserved words) Ù
ث٠"for", "let", "return" Ø¥ÙØ®.
+=======
+As we already know, a variable cannot have a name equal to one of the language-reserved words like "for", "let", "return" etc.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ٠باÙÙØ³Ø¨Ø© ÙØ®Ø§ØµÙØ© ÙÙ ÙØ§Ø¦ÙØ ÙØ§ ØªÙØ¬Ø¯ Ù
Ø«Ù ÙØ°Ù اÙÙÙÙØ¯:
@@ -351,7 +379,11 @@ alert( "blabla" in user ); // false, user.blabla ØºÙØ± Ù
ÙØ¬Ùد
ÙØ±Ø¬Ù Ù
ÙØ§ØØ¸Ø© Ø£ÙÙ ÙÙ Ø§ÙØ¬ÙØ© اÙÙØ³Ø±Ù Ù
Ù `in` ÙØ¬Ø¨ Ø£Ù ÙÙÙÙ ÙÙØ§Ù *اسÙ
Ø®Ø§ØµÙØ©*. ÙÙÙ٠عادة ÙØµÙا بÙÙ Ø¹ÙØ§Ù
ØªÙ ØªÙØµÙص.
+<<<<<<< HEAD
إذا ØØ°ÙÙØ§ Ø¹ÙØ§Ù
ات Ø§ÙØªÙØµÙØµØ ÙÙØ°Ø§ ÙØ¹ÙÙ Ù
ØªØºÙØ±ÙØ§Ø ÙØ¬Ø¨ Ø£Ù ÙØØªÙ٠عÙÙ Ø§ÙØ§Ø³Ù
اÙÙØ¹Ù٠اÙÙ
راد اختبارÙ. عÙ٠سبÙ٠اÙÙ
ثاÙ:
+=======
+If we omit quotes, that means a variable should contain the actual name to be tested. For instance:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let user = { age: 30 };
@@ -381,7 +413,7 @@ alert( "test" in obj ); // true, Ø§ÙØ®Ø§ØµÙØ© Ù
ÙØ¬Ùدة باÙÙØ¹Ù!
Ù
ÙØ§ÙÙ Ù
Ø«Ù ÙØ°Ù ØªØØ¯Ø« ÙØ§Ø¯Ø±Ø§ÙØ ÙØ£Ù `undefined` ÙØ§ ÙÙØ¨ØºÙ تعÙÙÙÙØ§ بشÙ٠ذاتÙ. عادة Ù
ا ÙØ³ØªØ®Ø¯Ù
`null` ÙÙÙÙÙ
ØºÙØ± اÙÙ
عرÙÙØ© أ٠اÙÙØ§Ø±ØºØ©. ÙØ°Ø§ Ù
عاÙ
Ù `in` ÙØ¹ØªØ¨Ø± ضÙÙØ§Ù ØºØ±ÙØ¨Ø§Ù ÙÙ Ø§ÙØ´ÙÙØ±Ø©.
-## The "for..in" loop
+## The "for..in" loop [#forin]
ÙÙÙ
Ø±ÙØ± عÙÙ ÙÙ Ù
ÙØ§ØªÙØ Ø§ÙÙØ§Ø¦ÙØ ÙÙØ¬Ø¯ Ø´Ù٠خاص آخر ÙÙØÙÙØ© loop: `for..in`. ÙØ°Ù Ø§ÙØÙÙØ© Ù
ختÙÙØ© تÙ
اÙ
ÙØ§ عÙ
ا Ø¯Ø±Ø³ÙØ§Ù سابÙÙØ§Ø Ø£Ù Ø§ÙØÙÙØ© `for(;;)`.
@@ -438,7 +470,11 @@ for (let code in codes) {
*/!*
```
+<<<<<<< HEAD
ÙØ¯ ÙØ³ØªØ®Ø¯ اÙÙØ§Ø¦Ù ÙØ§ÙØªØ±Ø§Ø ÙØ§Ø¦Ù
Ø© Ù
Ù Ø§ÙØ®Ùارات ÙÙÙ
ستخدÙ
. Ø¥Ù ÙÙØ§ ÙÙÙÙ
بعÙ
٠اÙÙ
ÙÙØ¹ بشÙÙ Ø±Ø¦ÙØ³Ù ÙÙØ²Ùار Ø§ÙØ£ÙÙ
Ø§Ù ÙØ¥ÙÙØ§ ÙØ±Ùد Ø£Ù ÙØ¸Ùر `49` Ù٠أÙ٠اÙÙØ§Ø¦Ù
Ø©.
+=======
+The object may be used to suggest a list of options to the user. If we're making a site mainly for a German audience then we probably want `49` to be the first.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ٠إذا ÙÙ
ÙØ§ بتشغÙ٠اÙÙÙØ¯, ÙØ¥ÙÙØ§ ÙØ±Ù ØµÙØ±Ø© Ù
ختÙÙØ© تÙ
اÙ
اÙ:
@@ -450,6 +486,7 @@ for (let code in codes) {
````smart header="خصائص Ø¹Ø¯Ø¯ÙØ©Ø Ù
ا ÙØ°Ø§Ø"
"Ø§ÙØ®ØµØ§Ø¦Øµ Ø§ÙØ±ÙÙ
ÙØ© integer property" Ù
ØµØ·ÙØ ÙØ¹ÙÙ ÙÙØ§ ÙØµÙا ÙÙ
Ù٠تØÙÙÙÙ Ù
Ù ÙØ¥Ù٠عدد دÙÙ Ø£Ù ÙØªØºÙر.
+<<<<<<< HEAD
ÙØ°Ø§, "49" Ù٠اسÙ
Ø®Ø§ØµÙØ© عددÙ, ÙØ£ÙÙ Ø¹ÙØ¯ تØÙÙÙ٠إÙ٠عدد ÙØ¥Ø±Ø¬Ø§Ø¹Ù ÙÙØµ, ÙØ¨ÙÙ ÙÙ
ا ÙÙ. ÙÙÙ "+49" Ù "1.2" are ÙÙØ³Ø§ ÙØ°ÙÙ:
```js run
@@ -457,6 +494,16 @@ for (let code in codes) {
alert( String(Math.trunc(Number("49"))) ); // "49", Ø§ÙØ®Ø§ØµÙØ© Ø§ÙØ¹Ø¯Ø¯ÙØ© Ø°Ø§ØªÙØ§
alert( String(Math.trunc(Number("+49"))) ); // "49" Ù
ختÙÙØ© ع٠"49+" => Ø¥Ø°ÙØ§ ÙÙØ³Øª Ø®Ø§ØµÙØ© Ø¹Ø¯Ø¯ÙØ©
alert( String(Math.trunc(Number("1.2"))) ); // "1" Ù
ختÙÙØ© ع٠"1.2" => Ø¥Ø°ÙØ§ ÙÙØ³Øª Ø®Ø§ØµÙØ© Ø¹Ø¯Ø¯ÙØ©
+=======
+So, `"49"` is an integer property name, because when it's transformed to an integer number and back, it's still the same. But `"+49"` and `"1.2"` are not:
+
+```js run
+// Number(...) explicitly converts to a number
+// Math.trunc is a built-in function that removes the decimal part
+alert( String(Math.trunc(Number("49"))) ); // "49", same, integer property
+alert( String(Math.trunc(Number("+49"))) ); // "49", not same "+49" â not integer property
+alert( String(Math.trunc(Number("1.2"))) ); // "1", not same "1.2" â not integer property
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
````
@@ -505,9 +552,15 @@ for (let code in codes) {
- Ù
ÙØ§ØªÙØ Ø§ÙØ®Ùاص ÙØ¬Ø¨ أ٠تÙÙÙ ÙØµØ§Ù أ٠رÙ
زا٠(عادة Ù
ا تÙÙÙ ÙØµØ§Ù).
- اÙÙÙÙ
ÙÙ
Ù٠أ٠تÙÙÙ Ù
٠أ٠ÙÙØ¹.
+<<<<<<< HEAD
ÙÙÙØµÙ٠إÙÙ Ø®Ø§ØµÙØ©, ÙÙ
ÙÙÙØ§ استخداÙ
:
- رÙ
ز اÙÙÙØ·Ø©: `obj.property`.
- رÙ
ز Ø§ÙØ£ÙÙØ§Ø³ اÙÙ
ربعة `obj["property"]`. تسÙ
Ø Ø§ÙØ£ÙÙØ§Ø³ اÙÙ
ربعة بأخذ اÙÙ
ÙØªØ§Ø Ù
Ù Ù
ØªØºÙØ±, Ù
ث٠`obj[varWithKey]`.
+=======
+To access a property, we can use:
+- The dot notation: `obj.property`.
+- Square brackets notation `obj["property"]`. Square brackets allow taking the key from a variable, like `obj[varWithKey]`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù
عاÙ
ÙØ§Øª إضاÙÙØ© Additional operators:
- ÙØØ°Ù Ø®Ø§ØµÙØ©: `delete obj.prop`.
diff --git a/1-js/04-object-basics/02-object-copy/article.md b/1-js/04-object-basics/02-object-copy/article.md
index 596520c95..aedfe0e66 100644
--- a/1-js/04-object-basics/02-object-copy/article.md
+++ b/1-js/04-object-basics/02-object-copy/article.md
@@ -37,7 +37,11 @@ let user = {
ÙØªÙ
تخزÙ٠اÙÙØ§Ø¦Ù ÙÙ Ù
ÙØ§Ù Ù
ا ÙÙ Ø§ÙØ°Ø§Ùرة (عÙ٠اÙÙÙ
ÙÙ Ù
Ù Ø§ÙØµÙرة)Ø ÙÙ ØÙÙ ÙØØªÙ٠اÙÙ
ØªØºÙØ± `user` (عÙ٠اÙÙØ³Ø§Ø±) عÙÙ "Ù
رجع" Ø¥ÙÙ ÙØ°Ø§ اÙÙ
ÙØ§Ù.
+<<<<<<< HEAD
ÙÙ
ÙÙÙØ§ Ø§ÙØªÙÙÙØ± ÙÙ Ù
ØªØºÙØ± اÙÙØ§Ø¦ÙØ Ù
ث٠`user`Ø ÙÙØ±ÙØ© ÙØ±Ù Ø¨ÙØ§ عÙÙØ§Ù اÙÙØ§Ø¦Ù.
+=======
+We may think of an object variable, such as `user`, like a sheet of paper with the address of the object on it.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¹ÙØ¯Ù
ا ÙÙÙÙ
بإجراء أ٠عÙ
ÙÙØ§Øª عÙ٠اÙÙØ§Ø¦ÙØ Ù
ث٠اÙÙØµÙ٠إÙÙ Ø®Ø§ØµÙØ© `user.name`Ø ÙÙÙÙ
Ù
ØØ±Ù JavaScript باÙÙØ¸Ø± Ø¥ÙÙ Ù
ا ÙÙØ¬Ø¯ Ù٠ذÙÙ Ø§ÙØ¹ÙÙØ§Ù ÙÙÙÙØ° Ø§ÙØ¹Ù
ÙÙØ© عÙ٠اÙÙØ§Ø¦Ù اÙÙØ¹ÙÙ.
@@ -100,6 +104,7 @@ alert(a == b); // false
ÙÙÙ
ÙØ§Ø±Ùات Ù
ث٠`obj1 > obj2` Ø£Ù ÙÙÙ
ÙØ§Ø±ÙØ© Ù
ع ÙÙÙ
Ø© Ø£ÙÙÙØ© `obj == 5`Ø ÙØªÙ
تØÙÙ٠اÙÙØ§Ø¦Ùات Ø¥ÙÙ ÙÙÙ
Ø£ÙÙÙØ©. Ø³ÙØ¯Ø±Ø³ ÙÙÙÙØ© عÙ
٠تØÙÙÙØ§Øª اÙÙØ§Ø¦Ùات ÙØ±ÙØ¨ÙØ§ Ø¬Ø¯ÙØ§Ø ÙÙÙÙ ÙÙÙÙ Ø§ÙØÙÙÙØ©Ø ØªØØªØ§Ø¬ ÙØ°Ù اÙÙ
ÙØ§Ø±Ùات ÙØ§Ø¯Ø±Ùا Ø¬Ø¯ÙØ§ - عادة Ù
ا ØªØ¸ÙØ± ÙØªÙجة خطأ ÙÙ Ø§ÙØ¨Ø±Ù
جة.
+<<<<<<< HEAD
## Ø§Ø³ØªÙØ³Ø§Ø® ÙØ¯Ù
Ø¬Ø Object.assign [#cloning-and-merging-object-assign]
ÙØ³Ø® اÙÙ
ØªØºÙØ± ÙÙØ´Ø¦ Ù
ؤشر آخر ÙÙÙØ³ اÙÙØ§Ø¦Ù.
@@ -235,6 +240,10 @@ alert(clone.sizes.width); // 51, ÙØ¬Ø¹Ù Ø§ÙØªØºÙÙØ± Ù
ئ٠Ù٠اÙÙ
ÙØ§
````smart header="ÙÙ
Ù٠تعدÙ٠اÙÙØ§Ø¦Ùات Ø§ÙØªÙ تÙ
تعرÙÙÙØ§ ب٠const"
آثار Ø¬Ø§ÙØ¨ÙØ© Ù
ÙÙ
Ø© ÙØªØ®Ø²Ù٠اÙÙØ§Ø¦Ùات ÙÙ
راجع Ù٠أÙÙ ÙÙ
Ù٠تعدÙÙ ÙØ§Ø¦Ù Ù
عر٠ب٠`const`.
+=======
+````smart header="Const objects can be modified"
+An important side effect of storing objects as references is that an object declared as `const` *can* be modified.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
عÙ٠سبÙ٠اÙÙ
ثاÙ:
@@ -257,10 +266,210 @@ alert(user.name); // Pete
ÙÙ
ع ذÙÙØ إذا ÙÙØ§ Ø¨ØØ§Ø¬Ø© ÙØ¹ÙÙØ§ Ø¥Ù٠جع٠خصائص اÙÙØ§Ø¦Ù Ø«Ø§Ø¨ØªØ©Ø ÙÙ
٠اÙÙ
Ù
Ù٠ذÙ٠باستخداÙ
طر٠Ù
ختÙÙØ© تÙ
اÙ
ÙØ§. Ø³ÙØ°Ùر ذÙÙ Ù٠اÙÙØµÙ .
````
+<<<<<<< HEAD
## Ù
ÙØ®Øµ
+=======
+## Cloning and merging, Object.assign [#cloning-and-merging-object-assign]
+
+So, copying an object variable creates one more reference to the same object.
+
+But what if we need to duplicate an object?
+
+We can create a new object and replicate the structure of the existing one, by iterating over its properties and copying them on the primitive level.
+
+Like this:
+
+```js run
+let user = {
+ name: "John",
+ age: 30
+};
+
+*!*
+let clone = {}; // the new empty object
+
+// let's copy all user properties into it
+for (let key in user) {
+ clone[key] = user[key];
+}
+*/!*
+
+// now clone is a fully independent object with the same content
+clone.name = "Pete"; // changed the data in it
+
+alert( user.name ); // still John in the original object
+```
+
+We can also use the method [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign).
+
+The syntax is:
+
+```js
+Object.assign(dest, ...sources)
+```
+
+- The first argument `dest` is a target object.
+- Further arguments is a list of source objects.
+
+It copies the properties of all source objects into the target `dest`, and then returns it as the result.
+
+For example, we have `user` object, let's add a couple of permissions to it:
+
+```js run
+let user = { name: "John" };
+
+let permissions1 = { canView: true };
+let permissions2 = { canEdit: true };
+
+*!*
+// copies all properties from permissions1 and permissions2 into user
+Object.assign(user, permissions1, permissions2);
+*/!*
+
+// now user = { name: "John", canView: true, canEdit: true }
+alert(user.name); // John
+alert(user.canView); // true
+alert(user.canEdit); // true
+```
+
+If the copied property name already exists, it gets overwritten:
+
+```js run
+let user = { name: "John" };
+
+Object.assign(user, { name: "Pete" });
+
+alert(user.name); // now user = { name: "Pete" }
+```
+
+We also can use `Object.assign` to perform a simple object cloning:
+
+```js run
+let user = {
+ name: "John",
+ age: 30
+};
+
+*!*
+let clone = Object.assign({}, user);
+*/!*
+
+alert(clone.name); // John
+alert(clone.age); // 30
+```
+
+Here it copies all properties of `user` into the empty object and returns it.
+
+There are also other methods of cloning an object, e.g. using the [spread syntax](info:rest-parameters-spread) `clone = {...user}`, covered later in the tutorial.
+
+## Nested cloning
+
+Until now we assumed that all properties of `user` are primitive. But properties can be references to other objects.
+
+Like this:
+```js run
+let user = {
+ name: "John",
+ sizes: {
+ height: 182,
+ width: 50
+ }
+};
+
+alert( user.sizes.height ); // 182
+```
+
+Now it's not enough to copy `clone.sizes = user.sizes`, because `user.sizes` is an object, and will be copied by reference, so `clone` and `user` will share the same sizes:
+
+```js run
+let user = {
+ name: "John",
+ sizes: {
+ height: 182,
+ width: 50
+ }
+};
+
+let clone = Object.assign({}, user);
+
+alert( user.sizes === clone.sizes ); // true, same object
+
+// user and clone share sizes
+user.sizes.width = 60; // change a property from one place
+alert(clone.sizes.width); // 60, get the result from the other one
+```
+
+To fix that and make `user` and `clone` truly separate objects, we should use a cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning" or "structured cloning". There's [structuredClone](https://developer.mozilla.org/en-US/docs/Web/API/structuredClone) method that implements deep cloning.
+
+
+### structuredClone
+
+The call `structuredClone(object)` clones the `object` with all nested properties.
+
+Here's how we can use it in our example:
+
+```js run
+let user = {
+ name: "John",
+ sizes: {
+ height: 182,
+ width: 50
+ }
+};
+
+*!*
+let clone = structuredClone(user);
+*/!*
+
+alert( user.sizes === clone.sizes ); // false, different objects
+
+// user and clone are totally unrelated now
+user.sizes.width = 60; // change a property from one place
+alert(clone.sizes.width); // 50, not related
+```
+
+The `structuredClone` method can clone most data types, such as objects, arrays, primitive values.
+
+It also supports circular references, when an object property references the object itself (directly or via a chain or references).
+
+For instance:
+
+```js run
+let user = {};
+// let's create a circular reference:
+// user.me references the user itself
+user.me = user;
+
+let clone = structuredClone(user);
+alert(clone.me === clone); // true
+```
+
+As you can see, `clone.me` references the `clone`, not the `user`! So the circular reference was cloned correctly as well.
+
+Although, there are cases when `structuredClone` fails.
+
+For instance, when an object has a function property:
+
+```js run
+// error
+structuredClone({
+ f: function() {}
+});
+```
+
+Function properties aren't supported.
+
+To handle such complex cases we may need to use a combination of cloning methods, write custom code or, to not reinvent the wheel, take an existing implementation, for instance [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) from the JavaScript library [lodash](https://lodash.com).
+
+## Summary
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
اÙÙØ§Ø¦Ùات تتÙ
تعÙÙÙÙØ§ ÙÙØ³Ø®Ùا باÙÙ
رجع. ÙØ¨Ù
عÙÙ Ø¢Ø®Ø±Ø ÙØ®Ø²Ù اÙÙ
ØªØºÙØ± ÙÙØ³ "ÙÙÙ
Ø© اÙÙØ§Ø¦Ù" ÙÙÙÙ "Ù
رجع" (عÙÙØ§Ù ÙÙ Ø§ÙØ°Ø§Ùرة) ÙÙÙÙÙ
Ø©. ÙØ°ÙÙØ Ø¹ÙØ¯ ÙØ³Ø® ÙØ°Ø§ اÙÙ
ØªØºÙØ± أ٠تÙ
Ø±ÙØ±Ù ÙÙØ³ÙØ· ÙØ¯Ø§ÙØ©Ø ÙØªÙ
ÙØ³Ø® ÙØ°Ø§ اÙÙ
Ø±Ø¬Ø¹Ø ÙÙÙØ³ اÙÙØ§Ø¦Ù ÙÙØ³Ù.
ÙÙ Ø§ÙØ¹Ù
ÙÙØ§Øª Ø§ÙØªÙ تتÙ
Ø¨ÙØ§Ø³Ø·Ø© اÙÙØ³Ø®Ø© (Ù
Ø«Ù Ø¥Ø¶Ø§ÙØ© ÙØØ°Ù Ø§ÙØ®Ùاص) ØªØØ¯Ø« عÙÙ ÙÙØ³ اÙÙØ§Ø¦Ù.
+<<<<<<< HEAD
ÙØ¹Ù
Ù ÙØ³Ø®Ø© ØÙÙÙÙØ© ÙÙ
ÙÙÙØ§ استخداÙ
`Object.assign` ÙÙ
ا ÙØ³Ù
Ù "shallow copy" (اÙÙØ§Ø¦Ùات Ø§ÙØ¯Ø§Ø®ÙÙØ© ØªÙØ³Ø® باÙÙ
ؤشر) Ø£Ù Ø¯Ø§ÙØ© "deep cloning" Ù
ث٠[\_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep).
+=======
+To make a "real copy" (a clone) we can use `Object.assign` for the so-called "shallow copy" (nested objects are copied by reference) or a "deep cloning" function `structuredClone` or use a custom cloning implementation, such as [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/04-object-basics/03-garbage-collection/article.md b/1-js/04-object-basics/03-garbage-collection/article.md
index cb9af14ff..a56b5748e 100644
--- a/1-js/04-object-basics/03-garbage-collection/article.md
+++ b/1-js/04-object-basics/03-garbage-collection/article.md
@@ -76,7 +76,11 @@ Now if we do the same:
user = null;
```
+<<<<<<< HEAD
...ÙÙ ÙØ°Ù Ø§ÙØØ§ÙØ© Ù
ا Ø²Ø§Ù Ø¨Ø§ÙØ§Ù
ÙØ§Ù اÙÙØµÙ٠اÙ٠اÙÙØ§Ø¦Ù ع٠طرÙ٠اÙÙ
ØªØºÙØ± Ø§ÙØ¹Ø§Ù
`admin`, ÙØ°Ø§ ÙÙÙ Ù
Ø®Ø²Ù Ø¨Ø§ÙØ°Ø§Ùرة. اذا تÙ
استخداÙ
اÙÙ
ØªØºÙØ± `admin` ÙÙ Ù
ÙØ§Ù أخر Ø§ÙØ¶Ø§ ÙÙØ§ ÙÙ
ÙÙ Ø§Ø²Ø§ÙØ© اÙÙØ§Ø¦Ù .
+=======
+...Then the object is still reachable via `admin` global variable, so it must stay in memory. If we overwrite `admin` too, then it can be removed.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## اÙÙØ§Ø¦Ùات اÙÙ
ترابطة
@@ -178,11 +182,19 @@ The basic garbage collection algorithm is called "mark-and-sweep".

+<<<<<<< HEAD
Ø«Ù
ÙØ¶Ø¹ Ø¹ÙØ§Ù
Ø© عÙÙ Ù٠اÙÙ
راجع اÙÙ
رتبطة بÙ:

...Ù Ù
راجعÙ
ÙØ°Ù٠ا٠اÙ
ÙÙ
+=======
+Then we follow their references and mark referenced objects:
+
+
+
+...And continue to follow further references, while possible:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11

@@ -191,23 +203,40 @@ The basic garbage collection algorithm is called "mark-and-sweep".

+<<<<<<< HEAD
ÙÙ
ÙÙÙØ§ تخÙÙ Ø§ÙØ¹Ù
ÙÙØ© ÙØµØ¨ دÙÙ ÙØ¨Ùر Ù
Ù Ø§ÙØ·Ùاء Ù
Ù Ø§ÙØ¬Ø°Ø± Ù Ø§ÙØ°Ù Ø³ÙØ³Ø±Ù Ø®ÙØ§Ù Ù٠اÙÙ
راجع Ù ÙØ¶Ø¹ Ø¹ÙØ§Ù
Ø© عÙÙ Ù٠اÙÙØ§Ø¦Ùات Ø§ÙØªÙ ÙÙ
Ù٠اÙÙØµÙ٠اÙÙÙØ§, ٠اÙÙØ§Ø¦Ùات Ø§ÙØªÙ ÙØ§ ÙÙ
Ù٠اÙÙØµÙ٠اÙÙÙØ§ ÙØªÙ
Ø§Ø²Ø§ÙØªÙا.
+=======
+That's the concept of how garbage collection works. JavaScript engines apply many optimizations to make it run faster and not introduce any delays into the code execution.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
تÙÙ Ù٠اÙÙ
بادئ Ø§ÙØªÙ ÙØ¹Ù
٠عÙÙ Ø§Ø³Ø§Ø³ÙØ§ جاÙ
ع اÙÙÙ
اÙ
Ø©. Ù
ØØ±Ù ا٠JavaScript ÙØ·Ø¨Ù Ø§ÙØ¹Ø¯Ùد Ù
Ù Ø§ÙØªØØ³ÙÙØ§Øª ÙØ¬Ø¹ÙÙ ÙØ¹Ù
٠بشÙ٠اسرع Ù Ø§ÙØ§ ÙØ¤Ø«Ø± عÙÙ Ø§ÙØ¢Ø¯Ø§Ø¡.
+<<<<<<< HEAD
بعض ÙØ°Ù Ø§ÙØªØØ³ÙÙØ§Øª:
+=======
+- **Generational collection** -- objects are split into two sets: "new ones" and "old ones". In typical code, many objects have a short life span: they appear, do their job and die fast, so it makes sense to track new objects and clear the memory from them if that's the case. Those that survive for long enough, become "old" and are examined less often.
+- **Incremental collection** -- if there are many objects, and we try to walk and mark the whole object set at once, it may take some time and introduce visible delays in the execution. So the engine splits the whole set of existing objects into multiple parts. And then clear these parts one after another. There are many small garbage collections instead of a total one. That requires some extra bookkeeping between them to track changes, but we get many tiny delays instead of a big one.
+- **Idle-time collection** -- the garbage collector tries to run only while the CPU is idle, to reduce the possible effect on the execution.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
- **Ù
جÙ
ÙØ¹Ø© Ø§ÙØ£Ø¬ÙاÙ** -- -- ÙØªÙ
ØªÙØ³ÙÙ
اÙÙØ§Ø¦Ùات اÙÙ Ù
جÙ
ÙØ¹ØªÙÙ "Ø§ÙØ¬Ø¯Ùدة", "اÙÙØ¯ÙÙ
Ø©", اÙÙØ«Ùر Ù
٠اÙÙØ§Ø¦Ùات ÙØªÙ
Ø§ÙØ´Ø§Ø¦Ùا Ù ØªØ¤Ø¯Ù ÙØ¸ÙÙØªÙا ٠تÙ
ÙØª بسرعة, ÙÙÙ
ÙÙ Ø§ÙØªØ®Ùص Ù
ÙÙØ§ بسرعة. اÙ
ا اÙÙØ§Ø¦Ùات Ø§ÙØªÙ ØªØ¹ÙØ´ ÙÙØªØ±Ø© Ø·ÙÙØ© ØªØµØ¨Ø "ÙØ¯ÙÙ
Ø©" Ù ÙØ§ ÙØªÙ
Ø§ÙØªØÙÙ Ù
ÙÙØ§ Ù Ø§Ø²Ø§ÙØªÙا بÙÙØ³ اÙÙØ«Ø§ÙØ©.
- **اÙÙ
جÙ
ÙØ¹Ø© اÙÙ
ØªØ²Ø§ÙØ¯Ø©** --ÙÙ ØØ§ÙØ© ÙØ¬Ùد Ø§ÙØ¹Ø¯Ùد Ù
٠اÙÙØ§Ø¦Ùات, Ù ØØ§ÙÙÙØ§ اÙÙ
Ø±ÙØ± ÙÙØ¶Ø¹ Ø¹ÙØ§Ù
Ø© عÙ٠اÙÙØ§Ø¦Ù ÙÙÙ Ù
رة ÙØ§ØØ¯Ø©, Ø³ÙØ³ØªÙÙÙ ÙØ°Ø§ بعضا Ù
٠اÙÙÙØª Ù
Ù
ا ÙØ¯ ÙØ¤Ø¯Ù اÙ٠بعض Ø§ÙØªØ£Ø®Ùر Ù٠عÙ
ÙÙØ© Ø§ÙØªÙÙÙØ°, ÙØ°ÙÙ ÙØØ§Ù٠جاÙ
ع اÙÙÙ
اÙ
Ø© ØªÙØ³ÙÙ
ÙÙØ³Ù اÙ٠اجزاء, ÙÙ Ø§ÙØ£Ø¬Ø²Ø§Ø¡ ÙØªÙ
استخداÙ
ÙØ§ ÙØØ¯ÙØ§ ÙØ§ØØ¯Ø© تÙÙ Ø§ÙØ£Ø®Ø±Ù, Ù
Ù
ا ÙØ¯ ÙØªØ·Ùب اÙÙ
Ø²ÙØ¯ Ù
Ù Ø§ÙØ§Ø¯Ø§Ø±Ø© ÙÙ
تابعة Ø§ÙØªØºÙÙØ±Ø§Øª ٠تسجÙÙÙØ§, Ù ÙÙÙ ØªØ£Ø®ÙØ±Ø§Øª Ø¹Ø¯ÙØ¯Ø© ØµØºÙØ±Ø© Ø§ÙØ¶Ù Ù
Ù ØªØ£Ø®ÙØ± ÙØ§ØØ¯ ÙØ¨Ùر.
+<<<<<<< HEAD
- **Ù
جÙ
ÙØ¹Ø© ÙÙØª Ø§ÙØ®Ù
ÙÙ** -- ÙØØ§Ù٠جاÙ
ع اÙÙÙ
اÙ
Ø© Ø§Ù ÙØ¹Ù
Ù ÙÙ ØØ§ÙØ© Ø§Ù ÙØØ¯Ø© اÙÙ
Ø¹Ø§ÙØ¬Ø© اÙÙ
Ø±ÙØ²ÙØ© (CPU) ÙÙ ØØ§ÙØ© Ø®Ù
ÙÙ ØØªÙ ÙØ§ ÙØ¤Ø«Ø± عÙ٠عÙ
ÙÙØ© Ø§ÙØªÙÙÙØ°.
+=======
+- Garbage collection is performed automatically. We cannot force or prevent it.
+- Objects are retained in memory while they are reachable.
+- Being referenced is not the same as being reachable (from a root): a pack of interlinked objects can become unreachable as a whole, as we've seen in the example above.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ§ÙÙ Ø§ÙØ¹Ø¯Ùد Ù
Ù Ø§ÙØªØØ³ÙÙØ§Øª ÙÙ Ø®ÙØ§Ø±Ø²Ù
ÙØ§Øª جاÙ
ع اÙÙÙ
اÙ
Ø©. ٠عÙÙ ÙØ¯Ø± Ù
ا Ø§ÙØ¯ ا٠اشرØÙا ÙÙØ§,ÙØ¬Ø¨ Ø§Ù ÙØªÙÙ٠٠ذÙÙ ÙØ£Ù اÙÙ
ØØ±Ùات Ø§ÙØ®ØªÙÙØ© تتبÙ٠طر٠٠ØÙÙÙ Ù
ختÙÙØ© Ù Ø§ÙØ£ÙÙ
Ù
٠ذÙÙ Ø§Ù Ø§ÙØ£Ø´Ùاء ØªØªØºÙØ± Ø¨ØªØªØ·ÙØ± اÙÙ
ØØ±Ùات, ÙØ°Ø§ ادرس Ø£ÙØ«Ø± "Ù
ÙØ¯Ù
ا" ÙØ¨Ø¯ÙÙ Ø§ÙØØ§Ø¬Ø© Ø§ÙØÙÙÙÙØ© ÙÙ
Ø¹Ø±ÙØªÙا ÙÙÙ ÙØ§ تستØÙ Ø§ÙØ¹Ùاء Ø§ÙØ§ ا٠ÙÙØª Ù Ø¨Ø§ÙØ·Ø¨Ø¹ تÙ
تÙÙ Ø§ÙØ´ØºÙ ÙÙÙ
Ø¹Ø±ÙØ© ÙØ§ÙØ±ÙØ§Ø¨Ø· Ø¨Ø§ÙØ£Ø³ÙÙ Ø³ØªØ³Ø§Ø¹Ø¯Ù Ø¨Ø§ÙØªØ£ÙÙØ¯.
## اÙÙ
ÙØ®Øµ
+<<<<<<< HEAD
اÙÙ
اÙÙÙØ§Ø· ÙØªØ¹Ø±ÙÙØ§:
- جاÙ
ع اÙÙÙ
اÙ
Ø© ÙØ¹Ù
٠بشÙ٠تÙÙØ§Ø¦Ù, ÙØ§ ÙÙ
Ù٠اجبار٠عÙÙ Ø§ÙØ¹Ù
٠ا٠اÙÙØ§ÙÙ
@@ -229,3 +258,10 @@ The basic garbage collection algorithm is called "mark-and-sweep".
اÙÙ
Ø¹Ø±ÙØ© اÙÙ
تعÙ
ÙØ© ÙÙÙ
ØØ±Ùات Ø¶Ø±ÙØ±ÙØ© ÙÙ ØÙÙ Ø§ÙØØ§Ø¬Ø© اÙÙ ØªØØ³ÙÙØ§Øª ذات Ù
ستÙÙ Ù
ØªØ·ÙØ±, ÙØ£Ù تخطط ÙÙ
Ø¹Ø±ÙØªÙا بعد Ø§Ù ØªØµØ¨Ø Ø¹ÙÙ Ù
Ø¹Ø±ÙØ© Ø¬ÙØ¯Ø© باÙÙØºØ© ÙÙÙ Ø¨Ø§ÙØªØ£ÙÙØ¯ Ø®Ø·ÙØ© ØÙÙÙ
Ø©.
+=======
+If you are familiar with low-level programming, more detailed information about V8's garbage collector is in the article [A tour of V8: Garbage Collection](https://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection).
+
+The [V8 blog](https://v8.dev/) also publishes articles about changes in memory management from time to time. Naturally, to learn more about garbage collection, you'd better prepare by learning about V8 internals in general and read the blog of [Vyacheslav Egorov](https://mrale.ph) who worked as one of the V8 engineers. I'm saying: "V8", because it is best covered by articles on the internet. For other engines, many approaches are similar, but garbage collection differs in many aspects.
+
+In-depth knowledge of engines is good when you need low-level optimizations. It would be wise to plan that as the next step after you're familiar with the language.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/04-object-basics/04-object-methods/7-calculator/task.md b/1-js/04-object-basics/04-object-methods/7-calculator/task.md
index 522e6403c..1a4d80c45 100644
--- a/1-js/04-object-basics/04-object-methods/7-calculator/task.md
+++ b/1-js/04-object-basics/04-object-methods/7-calculator/task.md
@@ -6,9 +6,15 @@
Ø£ÙØ´Ø¦ ÙØ§Ø¦ÙÙØ§ باسÙ
`calculator` ÙØÙÙ Ø§ÙØ¯ÙØ§Ù Ø§ÙØ«Ùاث Ø§ÙØªØ§ÙÙØ©:
+<<<<<<< HEAD
- `read()â` ØªØ·ÙØ¨ ÙÙÙ
تÙÙ ÙØªØÙØ¸ÙØ§ ÙØ®ØµØ§Ø¦Øµ اÙÙØ§Ø¦Ù.
- `sum()â` ØªÙØ±Ø¬Ùع Ù
جÙ
ÙØ¹ اÙÙÙÙ
اÙÙ
ØÙÙØ¸Ø©.
- `mul()â` تضرب اÙÙÙÙ
اÙÙ
ØÙÙØ¸Ø© ÙØªÙØ±Ø¬ÙØ¹ اÙÙØªÙجة.
+=======
+- `read()` prompts for two values and saves them as object properties with names `a` and `b` respectively.
+- `sum()` returns the sum of saved values.
+- `mul()` multiplies saved values and returns the result.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
let calculator = {
@@ -21,4 +27,3 @@ alert( calculator.mul() );
```
[demo]
-
diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js
index e98fe6410..a35c009cc 100644
--- a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js
+++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/solution.js
@@ -11,5 +11,6 @@ let ladder = {
},
showStep: function() {
alert(this.step);
+ return this;
}
};
\ No newline at end of file
diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js
index a2b17fcc4..b4f2459b7 100644
--- a/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js
+++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/_js.view/test.js
@@ -32,6 +32,14 @@ describe('Ladder', function() {
it('down().up().up().up() ', function() {
assert.equal(ladder.down().up().up().up().step, 2);
});
+
+ it('showStep() should return this', function() {
+ assert.equal(ladder.showStep(), ladder);
+ });
+
+ it('up().up().down().showStep().down().showStep()', function () {
+ assert.equal(ladder.up().up().down().showStep().down().showStep().step, 0)
+ });
after(function() {
ladder.step = 0;
diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md
index 5546be9f6..31876a26b 100644
--- a/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md
+++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/solution.md
@@ -23,7 +23,7 @@ let ladder = {
}
};
-ladder.up().up().down().up().down().showStep(); // 1
+ladder.up().up().down().showStep().down().showStep(); // shows 1 then 0
```
ÙÙ
ÙÙÙØ§ Ø£ÙØ¶Ø§ ÙØªØ§Ø¨Ø© استدعاء Ù
ستÙÙ ÙÙ Ù٠سطر ÙÙØµØ¨Ø سÙ٠اÙÙØ±Ø§Ø¡Ø© باÙÙØ³Ø¨Ø© ÙÙØ³ÙØ§Ø³Ù Ø§ÙØ£Ø·ÙÙ
@@ -33,7 +33,7 @@ ladder
.up()
.up()
.down()
- .up()
+ .showStep() // 1
.down()
- .showStep(); // 1
+ .showStep(); // 0
```
diff --git a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md
index fdf5d8020..3197168be 100644
--- a/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md
+++ b/1-js/04-object-basics/04-object-methods/8-chain-calls/task.md
@@ -4,7 +4,11 @@
# Ø§ÙØªØ³ÙسÙ
+<<<<<<< HEAD
ÙØ¯ÙÙØ§ اÙÙØ§Ø¦Ù `ladder` (سÙÙÙÙÙ
) Ø§ÙØ°Ù ÙØªÙØ Ø§ÙØµØ¹Ùد ÙØ§ÙÙØ²ÙÙ:
+=======
+There's a `ladder` object that allows you to go up and down:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
let ladder = {
@@ -21,19 +25,33 @@ let ladder = {
};
```
+<<<<<<< HEAD
Ø§ÙØ¢ÙØ Ø¥Ù Ø£Ø±Ø¯ÙØ§ اÙÙÙØ§Ù
بعدة استدعاءات Ù
تتاÙÙØ©Ø ÙÙ
ÙÙÙØ§ اÙÙÙØ§Ù
بÙ
ا ÙÙÙ:
+=======
+Now, if we need to make several calls in sequence, we can do it like this:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
ladder.up();
ladder.up();
ladder.down();
ladder.showStep(); // 1
+ladder.down();
+ladder.showStep(); // 0
```
+<<<<<<< HEAD
Ø¹ÙØ¯ÙÙÙ Ø§ÙØ´ÙÙØ±Ø© Ø§ÙØ®Ø§ØµØ© Ø¨Ø§ÙØ¯Ùا٠`up`Ø Ù `down`Ø Ù `showStep` ÙØ¬Ø¹Ù Ø§ÙØ§Ø³ØªØ¯Ø¹Ø§Ø¡Ø§Øª Ù
ØªØ³ÙØ³ÙØ© ÙÙ
ا ÙÙÙ:
+=======
+Modify the code of `up`, `down`, and `showStep` to make the calls chainable, like this:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
-ladder.up().up().down().showStep(); // 1
+ladder.up().up().down().showStep().down().showStep(); // shows 1 then 0
```
+<<<<<<< HEAD
ÙÙØ³ØªØ®Ø¯Ù
ÙØ°Ø§ اÙÙÙ
Ø· Ø¨ÙØ·Ø§Ù ÙØ§Ø³Ø¹ ÙÙ Ù
ÙØªØ¨Ø§Øª JavaScript
+=======
+Such an approach is widely used across JavaScript libraries.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/04-object-basics/04-object-methods/article.md b/1-js/04-object-basics/04-object-methods/article.md
index acbb2e8b8..c5078d42d 100644
--- a/1-js/04-object-basics/04-object-methods/article.md
+++ b/1-js/04-object-basics/04-object-methods/article.md
@@ -50,7 +50,7 @@ let user = {
// Ø£ÙÙØ§Ø ÙØ¹Ø±Ù Ø¯Ø§ÙØ©
function sayHi() {
alert("Hello!");
-};
+}
// أضÙÙ Ø§ÙØ¯Ø§ÙØ© ÙÙØ®Ø§ØµÙØ© ÙØ¥Ùشاء تابع
user.sayHi = sayHi;
@@ -80,7 +80,7 @@ user = {
// ÙØ¨Ø¯Ù Ø´ÙÙ Ø§ÙØ¯Ø§ÙØ© اÙÙ
ختصر Ø£ÙØ¶ÙØ Ø£ÙÙØ³ ÙØ°ÙÙØ
user = {
*!*
- sayHi() { // same as "sayHi: function()"
+ sayHi() { // same as "sayHi: function(){...}"
*/!*
alert("Hello");
}
@@ -89,7 +89,11 @@ user = {
ÙÙ
ÙÙÙØ§ ØØ°Ù اÙÙÙÙ
Ø© `"function"` ÙÙØªØ§Ø¨Ø© `sayHi()â ` ÙÙ
ا ÙÙ Ù
ÙØ¶Ø. ØÙÙÙØ©ÙØ Ø§ÙØªØ¹Ø¨ÙرÙÙ ÙÙØ³Ø§ Ù
تطابÙÙ٠تÙ
اÙ
ÙØ§Ø ÙÙØ¬Ø¯ Ø§Ø®ØªÙØ§Ùات Ø®ÙÙØ© Ù
تعÙÙØ© باÙÙØ±Ø§Ø«Ø© Ù٠اÙÙØ§Ø¦Ùات (Ø³ÙØªÙ
شرØÙا ÙØ§ØÙÙØ§)Ø ÙÙÙ ÙØ§ ÙÙØ¬Ø¯ Ù
Ø´ÙÙØ© Ø§ÙØ¢Ù. ÙÙØ¶Ù استخداÙ
Ø§ÙØµÙاغة Ø§ÙØ£Ùصر ÙÙ ÙÙ Ø§ÙØØ§ÙØ§Øª ØªÙØ±ÙØ¨ÙØ§.
+<<<<<<< HEAD
## اÙÙÙÙ
Ø© "this" ÙÙ Ø§ÙØ¯ÙاÙ
+=======
+To tell the truth, the notations are not fully identical. There are subtle differences related to object inheritance (to be covered later), but for now they do not matter. In almost all cases, the shorter syntax is preferred.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù
٠اÙÙ
ØªØ¹Ø§Ø±Ù Ø£Ù Ø§ÙØ¯ÙØ§Ù ØªØØªØ§Ø¬ ÙÙÙØµÙ٠إÙ٠اÙÙ
عÙÙÙ
ات اÙÙ
Ø®Ø²ÙØ© Ù٠اÙÙØ§Ø¦Ù ÙÙØªÙÙØ° عÙ
ÙÙØ§. Ù
Ø«ÙÙØ§Ø ÙØ¯ ØªØØªØ§Ø¬ Ø§ÙØ´ÙÙØ±Ø© Ø§ÙØªÙ بداخ٠`user.sayHi()â` ÙÙØ§Ø³Ù
اÙÙ
ستخدÙ
`user`. ÙÙØ§Ø
diff --git a/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md
index 8c1fea8eb..e932a201a 100644
--- a/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md
+++ b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md
@@ -4,14 +4,14 @@ importance: 2
# Two functions â one object
-Is it possible to create functions `A` and `B` such as `new A()==new B()`?
+Is it possible to create functions `A` and `B` so that `new A() == new B()`?
```js no-beautify
function A() { ... }
function B() { ... }
-let a = new A;
-let b = new B;
+let a = new A();
+let b = new B();
alert( a == b ); // true
```
diff --git a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md
index 60e7c373e..c862bec40 100644
--- a/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md
+++ b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md
@@ -6,7 +6,7 @@ importance: 5
Create a constructor function `Calculator` that creates objects with 3 methods:
-- `read()` asks for two values using `prompt` and remembers them in object properties.
+- `read()` prompts for two values and saves them as object properties with names `a` and `b` respectively.
- `sum()` returns the sum of these properties.
- `mul()` returns the multiplication product of these properties.
diff --git a/1-js/04-object-basics/06-constructor-new/article.md b/1-js/04-object-basics/06-constructor-new/article.md
index 6c0fa9039..870a95a79 100644
--- a/1-js/04-object-basics/06-constructor-new/article.md
+++ b/1-js/04-object-basics/06-constructor-new/article.md
@@ -1,8 +1,12 @@
# Ø§ÙØ¨Ø§ÙÙ ÙØ§ÙعاÙ
Ù "new"
+<<<<<<< HEAD
ÙÙÙØ´Ùئ اÙÙØ§Ø¦Ùات باستخداÙ
Ø§ÙØµÙغة Ø§ÙØ§Ø¹ØªÙØ§Ø¯ÙØ© اÙÙ
ختصرة `{...}`. ÙÙÙÙØ§ ÙØØªØ§Ø¬ ÙØ¥Ùشاء Ø§ÙØ¹Ø¯Ùد Ù
٠اÙÙØ§Ø¦Ùات اÙÙ
ØªØ´Ø§Ø¨ÙØ© ØºØ§ÙØ¨ÙØ§Ø Ù
Ø«Ù Ø§ÙØ¹Ø¯Ùد Ù
Ù
اÙÙ
ستخدÙ
ÙÙØ Ø£Ù Ø¹ÙØ§ØµØ± ÙÙØ§Ø¦Ù
Ø© ÙÙÙØ°Ø§. ÙÙ
Ù٠اÙÙÙØ§Ù
بذÙ٠باستخداÙ
Ø§ÙØ¯ÙØ§Ù Ø§ÙØ¨Ø§ÙÙØ© (constructor functions) ÙÙØ§Ø¦Ù ÙØ§ÙÙ
ÙØ¹Ø§Ù
ÙÙ
`"new"`.
+=======
+The regular `{...}` syntax allows us to create one object. But often we need to create many similar objects, like multiple users or menu items and so on.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## Ø§ÙØ¯Ø§ÙØ© Ø§ÙØ¨Ø§ÙÙØ©
@@ -57,6 +61,7 @@ isAdmin: false
### `**new function() { ⦠}â**`
+<<<<<<< HEAD
Ø¥Ù ÙØ§Ù ÙØ¯ÙÙØ§ Ø§ÙØ¹Ø¯Ùد Ù
Ù Ø§ÙØ£Ø³Ø·Ø± Ø§ÙØ¨Ø±Ù
Ø¬ÙØ©Ø ÙØ¬Ù
ÙØ¹Ùا Ø¹Ù Ø¥ÙØ´Ø§Ø¡ ÙØ§Ø¦Ù ÙØ§ØØ¯ Ù
ÙØ¹ÙÙÙÙØ¯Ø ÙØ¨Ø¥Ù
ÙØ§ÙÙØ§ تضÙ
ÙÙÙØ§ ÙÙ Ø¯Ø§ÙØ© باÙÙØ©Ø ÙÙØ°Ø§:
```
@@ -77,6 +82,26 @@ this.isAdmin = false;
ÙÙ
ÙÙÙØ§ ÙØØµ Ù
ا Ø¥Ù ÙØ§Ùت Ø§ÙØ¯Ø§ÙØ© ÙØ¯ Ø§Ø³ØªØ¯Ø¹ÙØª باستخداÙ
`new` أ٠دÙÙÙ Ù
Ù Ø¯Ø§Ø®Ù Ø§ÙØ¯Ø§ÙØ©Ø ÙØ°Ù٠باستخداÙ
Ø§ÙØ®Ø§ØµÙØ© Ø§ÙØ®Ø§ØµØ© `new.target`.
تÙÙÙ Ø§ÙØ®Ø§ØµÙØ© ÙØ§Ø±ØºØ© ÙÙ Ø§ÙØ§Ø³ØªØ¯Ø¹Ø§Ø¡Ø§Øª Ø§ÙØ¹Ø§Ø¯ÙØ©Ø ÙØªØ³Ø§ÙÙ Ø§ÙØ¯Ø§ÙØ© Ø§ÙØ¨Ø§ÙÙØ© إذا Ø§Ø³ØªÙØ¯Ø¹ÙÙÙØª باستخداÙ
`new`:
+=======
+Let's note once again -- technically, any function (except arrow functions, as they don't have `this`) can be used as a constructor. It can be run with `new`, and it will execute the algorithm above. The "capital letter first" is a common agreement, to make it clear that a function is to be run with `new`.
+
+````smart header="new function() { ... }"
+If we have many lines of code all about creation of a single complex object, we can wrap them in an immediately called constructor function, like this:
+
+```js
+// create a function and immediately call it with new
+let user = new function() {
+ this.name = "John";
+ this.isAdmin = false;
+
+ // ...other code for user creation
+ // maybe complex logic and statements
+ // local variables etc
+};
+```
+
+This constructor can't be called again, because it is not saved anywhere, just created and called. So this trick aims to encapsulate the code that constructs the single object, without future reuse.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
````
Inside a function, we can check whether it was called with `new` or without it, using a special `new.target` property.
@@ -139,7 +164,12 @@ alert( new SmallUser().name ); // John
ÙØ§ ØªØØªÙÙ Ø§ÙØ¯ÙØ§Ù Ø§ÙØ¨Ø§ÙÙØ© ØºØ§ÙØ¨Ùا عÙ٠تعÙÙÙ
Ø© Ø§ÙØ¥Ø¹Ø§Ø¯Ø© `return`. ÙØ°Ùر ÙÙØ§ ÙØ°Ø§ Ø§ÙØªØµØ±Ù Ø§ÙØ®Ø§Øµ Ø¹ÙØ¯ إرجاع اÙÙØ§Ø¦Ùات بغرض Ø´Ù
Ù٠جÙ
ÙØ¹ اÙÙÙØ§ØÙ.
+<<<<<<< HEAD
### **ØØ°Ù Ø§ÙØ£ÙÙØ§Ø³**
+=======
+````smart header="Omitting parentheses"
+By the way, we can omit parentheses after `new`:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
باÙÙ
ÙØ§Ø³Ø¨Ø©Ø ÙÙ
ÙÙÙØ§ ØØ°Ù Ø£ÙÙØ§Ø³ `new` ÙÙ ØØ§Ù ØºÙØ§Ø¨ اÙÙ
عاÙ
ÙØ§Øª Ù
ÙØ¹Ø§Ù
ÙÙØ§Øª:
diff --git a/1-js/04-object-basics/07-optional-chaining/article.md b/1-js/04-object-basics/07-optional-chaining/article.md
index 6df6d0c2a..221c8356c 100644
--- a/1-js/04-object-basics/07-optional-chaining/article.md
+++ b/1-js/04-object-basics/07-optional-chaining/article.md
@@ -25,14 +25,14 @@ That's the expected result. JavaScript works like this. As `user.address` is `un
In many practical cases we'd prefer to get `undefined` instead of an error here (meaning "no street").
-...And another example. In the web development, we can get an object that corresponds to a web page element using a special method call, such as `document.querySelector('.elem')`, and it returns `null` when there's no such element.
+...and another example. In Web development, we can get an object that corresponds to a web page element using a special method call, such as `document.querySelector('.elem')`, and it returns `null` when there's no such element.
```js run
// document.querySelector('.elem') is null if there's no element
let html = document.querySelector('.elem').innerHTML; // error if it's null
```
-Once again, if the element doesn't exist, we'll get an error accessing `.innerHTML` of `null`. And in some cases, when the absence of the element is normal, we'd like to avoid the error and just accept `html = null` as the result.
+Once again, if the element doesn't exist, we'll get an error accessing `.innerHTML` property of `null`. And in some cases, when the absence of the element is normal, we'd like to avoid the error and just accept `html = null` as the result.
How can we do this?
@@ -44,11 +44,19 @@ let user = {};
alert(user.address ? user.address.street : undefined);
```
-It works, there's no error... But it's quite inelegant. As you can see, the `"user.address"` appears twice in the code. For more deeply nested properties, that becomes a problem as more repetitions are required.
+It works, there's no error... But it's quite inelegant. As you can see, the `"user.address"` appears twice in the code.
-E.g. let's try getting `user.address.street.name`.
+Here's how the same would look for `document.querySelector`:
-We need to check both `user.address` and `user.address.street`:
+```js run
+let html = document.querySelector('.elem') ? document.querySelector('.elem').innerHTML : null;
+```
+
+We can see that the element search `document.querySelector('.elem')` is actually called twice here. Not good.
+
+For more deeply nested properties, it becomes even uglier, as more repetitions are required.
+
+E.g. let's get `user.address.street.name` in a similar fashion.
```js
let user = {}; // user has no address
@@ -58,7 +66,7 @@ alert(user.address ? user.address.street ? user.address.street.name : null : nul
That's just awful, one may even have problems understanding such code.
-Don't even care to, as there's a better way to write it, using the `&&` operator:
+There's a little better way to write it, using the `&&` operator:
```js run
let user = {}; // غرض ÙÙ
ستخدÙ
ÙØ§ ÙÙ
Ù٠عÙÙØ§Ù
@@ -92,6 +100,12 @@ alert( user?.address?.street ); // Ø³ÙØ¸Ùر ÙÙØ§ بدÙÙ ØØ¯ÙØ« خطأ un
The code is short and clean, there's no duplication at all.
+Here's an example with `document.querySelector`:
+
+```js run
+let html = document.querySelector('.elem')?.innerHTML; // will be undefined, if there's no element
+```
+
Reading the address with `user?.address` works even if `user` object doesn't exist:
```js run
@@ -107,9 +121,9 @@ E.g. in `user?.address.street.name` the `?.` allows `user` to safely be `null/un
ÙÙÙ٠إذا ÙØ§Ù Ø§ÙØºØ±Ø¶ `user` Ù
ÙØ¬Ùدا٠باÙÙØ¹ÙØ ÙÙØ¬Ø¨ أ٠تÙÙÙ Ø§ÙØ®ØµØ§Ø¦Øµ اÙÙØ³Ùطة Ù
ÙØ¬Ùدة ÙÙÙØµØ¯ Ø¨Ø§ÙØ®ØµØ§Ø¦Øµ اÙÙØ³Ùطة `user.address` Ù
Ø«ÙØ§Ù.
-For example, if according to our coding logic `user` object must exist, but `address` is optional, then we should write `user.address?.street`, but not `user?.address?.street`.
+For example, if according to our code logic `user` object must exist, but `address` is optional, then we should write `user.address?.street`, but not `user?.address?.street`.
-So, if `user` happens to be undefined due to a mistake, we'll see a programming error about it and fix it. Otherwise, coding errors can be silenced where not appropriate, and become more difficult to debug.
+Then, if `user` happens to be undefined, we'll see a programming error about it and fix it. Otherwise, if we overuse `?.`, coding errors can be silenced where not appropriate, and become more difficult to debug.
```
````warn header="اÙÙ
تØÙ٠اÙÙØ§Ùع ÙØ¨Ù Ø§ÙØªØ±ÙÙØ¨ `.?` ÙØ¬Ø¨ Ø£Ù ÙÙÙÙ Ù
عرÙÙØ§Ù"
@@ -126,7 +140,7 @@ The variable must be declared (e.g. `let/const/var user` or as a function parame
ÙÙ
ا تÙ
Ù Ø°ÙØ±Ù Ø¢ÙÙØ§ÙØ ÙÙÙÙ
Ø§ÙØªØ±ÙÙØ¨ `.?` بإÙÙØ§Ù عÙ
ÙÙØ© تÙÙÙÙ
اÙÙÙØ¯ Ø§ÙØ¨Ø±Ù
ج٠(ÙØ®ØªØµØ± Ø§ÙØ·Ø±ÙÙ) إذا ÙÙ
ÙÙ٠اÙÙØ³Ù
اÙÙØ³Ø§Ø±Ù (عÙÙ ÙØ³Ø§Ø± Ø§ÙØªØ±ÙÙØ¨) Ù
ÙØ¬ÙداÙ.
-So, if there are any further function calls or side effects, they don't occur.
+So, if there are any further function calls or operations to the right of `?.`, they won't be made.
For instance:
@@ -134,7 +148,7 @@ For instance:
let user = null;
let x = 0;
-user?.sayHi(x++); // no "sayHi", so the execution doesn't reach x++
+user?.sayHi(x++); // no "user", so the execution doesn't reach sayHi call and x++
alert(x); // ÙØ§ ÙØªÙ
Ø²ÙØ§Ø¯Ø© اÙÙÙÙ
Ø© 0
```
@@ -161,13 +175,13 @@ userAdmin.admin?.(); // I am admin
*/!*
*!*
-userGuest.admin?.(); // nothing (no such method)
+userGuest.admin?.(); // nothing happens (no such method)
*/!*
```
-Here, in both lines we first use the dot (`userAdmin.admin`) to get `admin` property, because we assume that the user object exists, so it's safe read from it.
+Here, in both lines we first use the dot (`userAdmin.admin`) to get `admin` property, because we assume that the `user` object exists, so it's safe read from it.
-Then `?.()` checks the left part: if the admin function exists, then it runs (that's so for `userAdmin`). Otherwise (for `userGuest`) the evaluation stops without errors.
+Then `?.()` checks the left part: if the `admin` function exists, then it runs (that's so for `userAdmin`). Otherwise (for `userGuest`) the evaluation stops without errors.
ÙÙ ØØ§Ù Ø§ÙØ±ØºØ¨Ø© باستخداÙ
Ø§ÙØ£ÙÙØ§Ø³ اÙÙ
Ø±Ø¨ÙØ¹Ø© `[]` Ø¨Ø¯ÙØ§Ù Ù
٠اÙÙÙØ·Ø© `.` ÙÙÙØµÙÙ ÙÙØ®Ùاص ضÙ
٠غرض Ø£Ù ÙØ§Ø¦Ù Ù
Ø§Ø Ø³ÙÙÙ Ø§ÙØªØ¹Ø¨Ùر `[].?` Ø¨Ø§ÙØºØ±Ø¶ Ø£ÙØ¶Ø§Ù. ÙØ¨Ø´ÙÙ Ù
شاب٠ÙÙØØ§ÙØ§Øª Ø§ÙØ³Ø§Ø¨ÙØ©Ø ÙØ³Ù
Ø ÙØ°Ø§ Ø§ÙØªØ¹Ø¨Ùر بشÙ٠آÙ
Ù ÙØ±Ø§Ø¡Ø©Ù Ø®Ø§ØµÙØ© Ø£Ù ØÙ٠ضÙ
٠غرض Ù
عÙÙÙ ÙØ¯ ÙØ§ ÙÙÙÙ Ù
ÙØ¬ÙداÙ.
@@ -178,7 +192,7 @@ let user1 = {
firstName: "John"
};
-let user2 = null;
+let user2 = null;
alert( user1?.[key] ); // John
alert( user2?.[key] ); // undefined
@@ -191,18 +205,22 @@ delete user?.name; // سÙÙÙÙ
Ø¨ØØ°Ù اسÙ
اÙÙ
ستخدÙ
ÙÙ ØØ§Ù Ù
```
````warn header="We can use `?.` for safe reading and deleting, but not writing"
-The optional chaining `?.` has no use at the left side of an assignment.
+The optional chaining `?.` has no use on the left side of an assignment.
For example:
```js run
let user = null;
+<<<<<<< HEAD
user?.name = "John"; // ÙØ³ÙØØ¯Ø« Ø®Ø·Ø£Ø ÙØ£Ù ÙØ°Ù Ø§ÙØ·Ø±ÙÙØ© ÙØ§ تعÙ
Ù
// ÙØ£ÙÙ Ø³ÙØªÙ
تÙÙÙÙ
ÙØ§ عÙ٠أÙ
// undefined = "John"
+=======
+user?.name = "John"; // Error, doesn't work
+// because it evaluates to: undefined = "John"
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
-It's just not that smart.
````
## Summary
@@ -217,4 +235,4 @@ The optional chaining `?.` syntax has three forms:
ÙØ¥Ø°Ø§ ÙØ§Ù ÙØ¯ÙÙØ§ خصائص Ù
ØªØ¯Ø§Ø®ÙØ© ÙÙÙ
ا بÙÙÙØ§Ø ÙÙØ³Ù
Ø ØªØ³ÙØ³Ù Ù
Ù Ø§ÙØªØ±ÙÙØ¨ `.?` Ø¨ÙØ±Ø§Ø¦ØªÙا بشÙÙ٠آÙ
Ù.
-Still, we should apply `?.` carefully, only where it's acceptable that the left part doesn't exist. So that it won't hide programming errors from us, if they occur.
+Still, we should apply `?.` carefully, only where it's acceptable, according to our code logic, that the left part doesn't exist. So that it won't hide programming errors from us, if they occur.
diff --git a/1-js/04-object-basics/08-symbol/article.md b/1-js/04-object-basics/08-symbol/article.md
index 23e6a0580..ac2104bc2 100644
--- a/1-js/04-object-basics/08-symbol/article.md
+++ b/1-js/04-object-basics/08-symbol/article.md
@@ -8,9 +8,22 @@
(symbol)
. ÙÙØ³Øª رÙÙ
ا Ø£Ù ÙÙÙ
Ù Ù
ÙØ·ÙÙÙ (boolean) ÙØ¥ÙÙ
ا Ø¹Ø¨Ø§Ø±Ù Ø¹Ù ÙØµÙص أ٠رÙ
ÙØ², ÙÙØ· ÙØ°Ù٠اÙÙÙØ¹ÙÙ.
+<<<<<<< HEAD
ÙÙØ¯ استخدÙ
ÙØ§ ØØªÙ Ø§ÙØ¢Ù اÙÙØµ ÙÙØ·. ÙÙÙØ§ ÙØ±Ù اÙÙÙØ§Ø¦Ø¯ Ø§ÙØªÙ ÙÙ
Ù٠أ٠تÙÙØ±Ùا ÙÙØ§ Ø§ÙØ±Ù
ÙØ².
## Ø§ÙØ±Ù
ÙØ²
+=======
+By specification, only two primitive types may serve as object property keys:
+
+- string type, or
+- symbol type.
+
+Otherwise, if one uses another type, such as number, it's autoconverted to string. So that `obj[1]` is the same as `obj["1"]`, and `obj[true]` is the same as `obj["true"]`.
+
+Until now we've been using only strings.
+
+Now let's explore symbols, see what they can do for us.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙÙ
Ø© رÙ
ز ÙÙ Ø§ÙØ¥ÙجÙÙØ²Ù٠تعÙÙ Ù
Ø¹ÙØ±ÙÙÙ ÙØ±Ùد Ù
Ù ÙÙØ¹Ù Ø£Ù ÙØ§ شئ Ù
Ù
اث٠ÙÙ
Unique Identifier.
@@ -18,18 +31,25 @@ Unique Identifier.
ÙÙ
ÙÙ Ø¥ÙØ´Ø§Ø¡ ÙÙÙ
Ù Ù
Ù ÙÙØ¹ Ø§ÙØ±Ù
ز باستخداÙ
Ø§ÙØ¯Ø§ÙÙ `Symbol()`:
```js
-// id is a new symbol
let id = Symbol();
```
+<<<<<<< HEAD
Ø¹ÙØ¯ Ø§ÙØ¥Ùشاء, ÙÙ
ÙÙÙØ§ إعطاء Ø§ÙØ±Ù
ز ÙØµÙÙØ§ (ÙÙÙ
Ù٠تسÙ
ÙØªÙ Ø£ÙØ¶Ø§ إسÙ
Ø§ÙØ±Ù
ز), ÙÙØ°Ø§ Ù
ÙÙØ¯ ØºØ§ÙØ¨Ø§ ÙÙ Ø§ÙØ¨ØØ« Ø¹Ù Ø§ÙØ£Ø®Ø·Ø§Ø¡ ÙØÙÙØ§.
+=======
+Upon creation, we can give symbols a description (also called a symbol name), mostly useful for debugging purposes:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
// id is a symbol with the description "id"
let id = Symbol('id');
```
+<<<<<<< HEAD
Ø¥Ù Ø§ÙØ±Ù
ÙØ² Ù
ضÙ
ÙÙ Ø¨ØªÙØ±ÙÙØ¯Ùا. ØØªÙ ÙÙ ØØ§ÙØ© Ø¥ÙØ´Ø§Ø¡ عدة رÙ
ÙØ² بÙÙØ³ اÙÙØµÙ, ÙÙÙÙÙÙ
Ù
ختÙÙÙÙ Ù٠اÙÙÙÙ
Ù. ÙØ§ÙÙØµÙ Ù
جرد ÙÙØ³ÙÙ
ÙØ§ ÙØ¤Ø«Ø± عÙÙ Ø£Ù Ø´ÙØ¡.
+=======
+Symbols are guaranteed to be unique. Even if we create many symbols with exactly the same description, they are different values. The description is just a label that doesn't affect anything.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
عÙ٠سبÙ٠اÙÙ
ثاÙ, ÙØ°Ø§Ù Ø§ÙØ±Ù
زا٠ÙÙÙ
ا ÙÙØ³ اÙÙØµÙ -- ÙÙÙÙÙÙ
ا ØºÙØ± Ù
تساÙÙÙÙ:
@@ -46,10 +66,17 @@ alert(id1 == id2); // false
(Ruby)
Ø£Ù Ø£Ù ÙØºØ© برÙ
جة Ø£Ø®Ø±Ù ÙØ¯ÙÙØ§ شئ ÙØ±Ùب Ù
Ù Ø§ÙØ±Ù
ÙØ² ÙÙØ§ ØªØØªØ§Ø±
+<<<<<<< HEAD
````warn header="Ø§ÙØ±Ù
ÙØ² ÙØ§ تتØÙ٠إÙÙ ÙØµ تÙÙØ§Ø¦ÙاÙ"
Ø£ØºÙØ¨ اÙÙÙÙ
ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙÙ
Ù٠تØÙÙÙÙØ§ ضÙ
ÙÙÙØ§ Ø¥ÙÙ ÙØµ (string).
عÙ٠سبÙ٠اÙÙ
ثاÙ, ÙÙ
ÙÙÙØ§ Ø£Ù ÙØ¹Ø±Ø¶ Ø£Ù ÙÙÙ
Ù ÙÙ Ø¯Ø§ÙØ© Ø§ÙØªÙبÙÙ (`alert()`),
ÙØ³ØªØ¹Ù
Ù, ÙÙÙÙ Ø§ÙØ±Ù
ÙØ² (Symbols) ÙÙØ§ طابع خاص. ÙÙØ§ تسر٠عÙÙÙÙ
اÙÙØ§Ø¹Ø¯Ù ÙÙØ³Ùا.
+=======
+So, to summarize, a symbol is a "primitive unique value" with an optional description. Let's see where we can use them.
+
+````warn header="Symbols don't auto-convert to a string"
+Most values in JavaScript support implicit conversion to a string. For instance, we can `alert` almost any value, and it will work. Symbols are special. They don't auto-convert.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
عÙ٠سبÙ٠اÙÙ
ثاÙ, ÙØ°Ø§ اÙÙÙØ¯ Ø³ÙØ¤Ø¯Ù Ø¥Ù٠ظÙÙØ± خطأ:
@@ -62,9 +89,14 @@ alert(id); // TypeError: Cannot convert a Symbol value to a string
ÙØ°Ø§ ÙÙ
ÙØ¹ Ø§ÙØ£Ø®Ø·Ø§Ø¡ ØºÙØ± اÙÙ
ÙØµÙدÙ, ÙØ£Ù اÙÙØµÙص ÙØ§ÙرÙ
ÙØ² Ù
ختÙÙÙ٠تÙ
اÙ
ÙÙØ§ ÙØ¬Ø¨ Ø£Ù ÙØªÙ
تغÙÙØ± ÙØ§ØØ¯ Ø¥ÙÙ Ø§ÙØ¢Ø®Ø± ع٠طرÙÙ Ø§ÙØ®Ø·Ø£.
+<<<<<<< HEAD
إذا ÙÙØ§ ÙØ±Ùد Ø£Ù ÙØ¹Ø±Ø¶ Ø§ÙØ±Ù
ز ÙÙ
ا ÙÙ, ÙØ¥ÙÙØ§ ÙØØªØ§Ø¬ Ø¥ÙÙ Ø£Ù ÙØ³ØªØ¯Ø¹Ù Ø§ÙØ¯Ø§ÙÙ
`.toString()`
Ù
ع ÙØ°Ø§ Ø§ÙØ±Ù
ز, ÙØ§ÙÙ
Ø«Ø§Ù Ø£Ø¯ÙØ§Ù:
+=======
+If we really want to show a symbol, we need to explicitly call `.toString()` on it, like here:
+
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let id = Symbol("id");
*!*
@@ -72,9 +104,14 @@ alert(id.toString()); // Symbol(id), now it works
*/!*
```
+<<<<<<< HEAD
Ø£Ù ÙØ³ØªØ¯Ø¹Ù Ø§ÙØ®Ø§ØµÙÙ
`symbol.description`
ÙØ¹Ø±Ø¶ اÙÙØµÙ ÙÙØ·:
+=======
+Or get `symbol.description` property to show the description only:
+
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let id = Symbol("id");
*!*
@@ -86,9 +123,14 @@ alert(id.description); // id
## Ø§ÙØ®ØµØ§Ø¦Øµ اÙÙ
Ø®ÙÙÙ
+<<<<<<< HEAD
باستخداÙ
Ø§ÙØ±Ù
ÙØ² ÙÙ
ÙÙÙØ§ Ø£Ù ÙÙØ´Ø¦ خصائص Ù
Ø®ÙÙÙ ÙÙØ§Ø¦Ù Ù
ا
(object)
ØÙØ« ÙØ§ ÙÙ
ÙÙ ÙØ£Ù جزء آخر Ù٠اÙÙÙØ¯ Ø£Ù ÙØµÙ Ø¥ÙÙÙØ§ ÙÙØ§ Ø£Ù ÙØ¹Ø¯Ù ÙÙÙ
ØªÙØ§ ع٠طرÙÙ Ø§ÙØ®Ø·Ø£.
+=======
+
+Symbols allow us to create "hidden" properties of an object, that no other part of code can accidentally access or overwrite.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
عÙ٠سبÙ٠اÙÙ
ثاÙ, إذا ÙÙØ§ ÙØ¹Ù
٠عÙÙ ÙØ§Ø¦Ù
`user`
@@ -114,9 +156,15 @@ alert(user[id]); // we can access the data using the symbol as the key
Ø¨Ø¯ÙØ§ Ù
٠اÙÙØµ
`"id"` Ø
+<<<<<<< HEAD
ØÙØ« أ٠اÙÙØ§Ø¦Ù `user` ÙÙØªÙ
Ù ÙÙÙØ¯ خارج٠ÙÙØ°Ø§ اÙÙÙØ¯ ÙØ¹Ù
Ù Ø¬ÙØ¯Ø§, إذا ÙÙØ§ ÙØµØ Ø£Ù ÙØ¶Ù٠أ٠خاصÙÙ ÙÙØ°Ø§ اÙÙØ§Ø¦Ù. ÙÙÙÙ Ø§ÙØ±Ù
ز ÙØ§ ÙÙ
Ù٠اÙÙØµÙ٠إÙÙ٠ع٠طرÙÙ Ø§ÙØ®Ø·Ø£ Ù
ث٠اÙÙØµ ØÙØ« أ٠اÙÙÙØ¯ Ø§ÙØ®Ø§Ø±Ø¬Ù ÙØ§ ÙÙ
ÙÙ Ø£Ù ÙØ±Ø§Ù Ù
Ù Ø§ÙØ£Ø³Ø§Ø³, ÙÙØ°ÙÙ ÙØ°Ù Ø§ÙØ·Ø±ÙÙÙ ØªÙØ¹Ø¯ صØÙØÙ.
تخÙÙ Ø£ÙØ¶Ø§ Ù٠أ٠ÙÙØ§Ù Ø¨Ø±ÙØ§Ù
ج (script) آخر ÙØ±Ùد Ø£Ù ÙØ¶ÙÙ Ø®Ø§ØµÙØ© بداخ٠اÙÙØ§Ø¦Ù `user` ÙØ£ØºØ±Ø§Ø¶Ù Ø§ÙØ®Ø§ØµÙ, ÙØ°Ø§ Ø§ÙØ¨Ø±ÙاÙ
ج Ø§ÙØ¢Ø®Ø± ÙÙ
ÙÙ٠أ٠ÙÙÙÙ Ù
ÙØªØ¨Ù Ù
بÙÙØ© Ø¨Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙÙØ°ÙÙ ÙØ¥Ù ÙØ°Ù Ø§ÙØ¨Ø±Ø§Ù
ج ÙØ§ ØªØ¹Ø±Ù Ø´ÙØ¦Ø§ Ø¹Ù Ø¨Ø¹Ø¶ÙØ§ Ø§ÙØ¨Ø¹Ø¶.
+=======
+As `user` objects belong to another codebase, it's unsafe to add fields to them, since we might affect pre-defined behavior in that other codebase. However, symbols cannot be accessed accidentally. The third-party code won't be aware of newly defined symbols, so it's safe to add symbols to the `user` objects.
+
+Also, imagine that another script wants to have its own identifier inside `user`, for its own purposes.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ°ÙÙ ÙØ°Ø§ Ø§ÙØ¨Ø±ÙاÙ
ج ÙÙ
ÙÙ٠أ٠ÙÙØ´Ø¦
`Symbol("id")`
@@ -183,11 +231,15 @@ for (let key in user) alert(key); // name, age (no symbols)
*/!*
// the direct access by the symbol works
-alert( "Direct: " + user[id] );
+alert( "Direct: " + user[id] ); // Direct: 123
```
+<<<<<<< HEAD
ÙØ£Ùضا ÙØªÙ
تجاÙÙ Ø§ÙØ®ØµØ§Ø¦Øµ Ù
Ù ÙÙØ¹ Ø§ÙØ±Ù
ز Ø¹ÙØ¯ استخداÙ
`Object.keys(user)`. ÙØ£Ù ÙØ°Ø§ جزء Ù
٠اÙÙ
بدأ Ø§ÙØ¹Ø§Ù
"Ø¥Ø®ÙØ§Ø¡ Ø§ÙØ®ØµØ§Ø¦Øµ Ø§ÙØ±Ù
زÙÙ"
"hiding symbolic properties". ÙØ¨Ø§ÙÙ
ث٠إذا ÙØ§Ù ÙÙØ§Ù Ø£Ù Ø¨Ø±ÙØ§Ù
ج آخر ÙÙÙÙ
Ø£Ù Ù
ÙØªØ¨Ù تÙÙÙ
Ø¨Ø§ÙØªÙرار عÙÙ Ø§ÙØ®ØµØ§Ø¦Øµ ÙÙ ÙØ°Ø§ اÙÙØ§Ø¦Ù ÙØ¥ÙÙØ§ ÙÙ ØªØ³ØªØ·ÙØ¹ أ٠تص٠إÙÙ Ø§ÙØ®Ø§ØµÙÙ Ù
Ù ÙÙØ¹ Ø§ÙØ±Ù
ز.
+=======
+[Object.keys(user)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) also ignores them. That's a part of the general "hiding symbolic properties" principle. If another script or a library loops over our object, it won't unexpectedly access a symbolic property.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
عÙ٠اÙÙÙÙØ¶ تÙ
اÙ
ا ÙØ¥Ù
[Object.assign](mdn:js/Object/assign)
@@ -237,12 +289,20 @@ alert(id === idAgain); // true
```smart header="ÙØ°Ø§ ÙØ¨Ø¯Ù Ù
Ø«Ù ÙØºØ© Ø§ÙØ¨Ø±Ù
ج٠Ruby"
Ù٠بعض ÙØºØ§Øª Ø§ÙØ¨Ø±Ù
ج٠Ù
ث٠Ruby ÙØ¥Ù ÙÙØ§Ù رÙ
Ø²ÙØ§ ÙÙ٠إسÙ
.
+<<<<<<< HEAD
ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙÙ
ا ÙØ±Ù ÙØ¥Ù ÙØ°Ø§ صØÙØ Ø¨Ø§ÙÙØ³Ø¨Ø© Ø¥ÙÙ Ø§ÙØ±Ù
ÙØ² Ø§ÙØ¹Ø§Ù
Ù.
+=======
+In JavaScript, as we can see, that's true for global symbols.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
### Symbol.keyFor
+<<<<<<< HEAD
باÙÙØ³Ø¨Ø© Ø¥ÙÙ Ø§ÙØ±Ù
ÙØ² Ø§ÙØ¹Ø§Ù
Ù ÙØ¥ÙÙ ÙØ§ÙÙØ¬Ø¯ `Symbol.for(key)` Ø§ÙØªÙ تÙÙÙ
بإرجاع Ø§ÙØ±Ù
ز باستخداÙ
Ø§ÙØ¥Ø³Ù
ÙÙØ·Ø ÙÙÙÙ ÙÙØ¬Ø¯ Ø£ÙØ¶Ø§ Ø§ÙØ¹Ùس `Symbol.keyFor(sym)` Ø§ÙØ°Ù ÙÙÙÙ
بإرجاع Ø§ÙØ¥Ø³Ù
باستخداÙ
Ø§ÙØ±Ù
ز Ø§ÙØ¹Ø§Ù
.
+=======
+We have seen that for global symbols, `Symbol.for(key)` returns a symbol by name. To do the opposite -- return a name by global symbol -- we can use: `Symbol.keyFor(sym)`:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
عÙ٠سبÙ٠اÙÙ
ثاÙ:
@@ -258,7 +318,11 @@ alert(Symbol.keyFor(sym2)); // id
Ø§ÙØ¯Ø§ÙÙ `Symbol.keyFor` Ø¹ÙØ¯Ù
ا تعÙ
٠تÙÙÙ
باستخداÙ
Ù
ÙØ§Ù تسجÙÙ Ø§ÙØ±Ù
ÙØ² Ø§ÙØ¹Ø§Ù
ÙÙØ¨ØØ« ع٠إسÙ
ÙÙØ±Ù
ز, ÙÙØ°ÙÙ ÙØ¥ÙÙØ§ ÙØ§ تعÙ
Ù Ø¥ÙØ§ Ù
ع Ø§ÙØ±Ù
ÙØ² Ø§ÙØ¹Ø§Ù
Ù. ÙØ¥Ø°Ø§ ÙØ§Ù Ø§ÙØ±Ù
ز ØºÙØ± عاÙ
ÙÙÙ ØªØ³ØªØ·ÙØ¹ Ø¥ÙØ¬Ø§Ø¯Ù ÙØ³ØªÙÙÙ
بإرجاع `undefined`.
+<<<<<<< HEAD
ÙÙØ§Ù بأ٠Ù٠رÙ
ز ÙÙ
ÙÙ Ø§ÙØ®Ø§ØµÙÙ `description`.
+=======
+That said, all symbols have the `description` property.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
عÙ٠سبÙ٠اÙÙ
ثاÙ:
@@ -298,12 +362,22 @@ alert(localSymbol.description); // name
ÙØªÙ
استخداÙ
Ø§ÙØ±Ù
ÙØ² ÙÙ ØØ§ÙتÙÙ:
+<<<<<<< HEAD
1. خصائص اÙÙØ§Ø¦Ù اÙÙ
Ø®ÙÙÙ.
+=======
+1. "Hidden" object properties.
+
+ If we want to add a property into an object that "belongs" to another script or a library, we can create a symbol and use it as a property key. A symbolic property does not appear in `for..in`, so it won't be accidentally processed together with other properties. Also it won't be accessed directly, because another script does not have our symbol. So the property will be protected from accidental use or overwrite.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
إذا ÙÙØ§ ÙØ±Ùد Ø£Ù ÙØ¶Ù٠خاصÙ٠إÙÙ ÙØ§Ø¦Ù ÙØ§ ÙÙØªÙ
٠إÙÙ ÙØ°Ø§ اÙÙÙØ¯ ب٠إÙÙ Ø¨Ø±ÙØ§Ù
ج آخر Ø£Ù Ù
ÙØªØ¨ÙØ ÙØ¹Ùدئذ ÙÙ
ÙÙÙØ§ Ø¥ÙØ´Ø§Ø¡ رÙ
ز ÙØ§Ø³ØªØ®Ø¯Ø§Ù
Ù ÙØ®Ø§ØµÙÙ. ÙØ§ÙخاصÙÙ Ù
Ù ÙÙØ¹ Ø§ÙØ±Ù
ز ÙØ§ ØªØ¸ÙØ± ÙÙ Ø§ÙØªÙرار `for .. in`, ÙÙØ°ÙÙ ÙØ§ ÙÙ
Ù٠اÙÙØµÙ٠إÙÙ Ø§ÙØ®Ø§ØµÙ٠ع٠طرÙÙ Ø§ÙØ®Ø·Ø£ أ٠أ٠تتعارض Ù
ع Ø£Ù Ø®Ø§ØµÙØ© Ø£Ø®Ø±Ù ÙØ°ÙÙ ÙØ£Ù Ø§ÙØ¨Ø±ÙاÙ
ج Ø§ÙØ¢Ø®Ø± ÙØ§ ÙÙ
ÙÙ Ø§ÙØ±Ù
ز Ø§ÙØ®Ø§Øµ Ø¨ÙØ§. ÙØ¨Ø§ÙتاÙÙ Ø³ØªØ¸Ù Ø§ÙØ®Ø§ØµÙÙ Ù
ØÙ
ÙÙ Ù
٠اÙÙØµÙ٠إÙÙÙØ§ Ø£Ù Ø§ÙØªØ¹Ø¯Ù٠عÙÙÙØ§.
ÙÙØ°ÙÙ ÙÙ
ÙÙÙØ§ Ø£Ù ÙÙØ®Ù٠أ٠شئ Ø¨Ø¯Ø§Ø®Ù ÙØ§Ø¦Ùات ÙØØªØ§Ø¬ÙØ§ ÙÙØ§ ÙØ³ØªØ·Ùع Ø£Ù Ø¨Ø±ÙØ§Ù
ج اÙÙØµÙ٠إÙÙÙØ§ باستخداÙ
Ø§ÙØ®ØµØ§Ø¦Øµ Ù
Ù ÙÙØ¹ Ø§ÙØ±Ù
ÙØ².
+<<<<<<< HEAD
2. ÙÙØ§Ù اÙÙØ«Ùر Ù
Ù Ø§ÙØ±Ù
ÙØ² اÙÙ
ÙØ¬Ùد٠باÙÙØ¹Ù ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØ§Ùت٠ÙÙ
Ù٠اÙÙØµÙ٠إÙÙÙØ§ ع٠طرÙÙ `Symbol.*`. ÙÙÙ
ÙÙÙØ§ استخداÙ
ÙÙ
ÙØªØºÙÙØ± بعض Ø§ÙØ³ÙÙ٠اÙÙ
ÙØ¬Ùد باÙÙØ¹Ù Ù٠اÙÙØºÙ. عÙ٠سبÙ٠اÙÙ
Ø«Ø§Ù ÙØ¥ÙÙØ§ ÙÙ Ù
ÙØ¶Ùع Ù
ÙØ¨Ù Ø³ÙØ³ØªØ®Ø¯Ù
`Symbol.iterator` Ù
Ù Ø£Ø¬Ù Ø§ÙØªÙØ±Ø§Ø±ÙØ§Øª [iterables](info:iterable) ÙØºÙØ±ÙØ§.
عÙ
ÙÙÙØ§Ø ÙØ¥Ù Ø§ÙØ±Ù
ÙØ² ÙØ§ تÙÙÙ Ù
Ø®ÙÙØ© باÙÙØ§Ù
Ù. ÙÙÙÙ ÙÙØ§Ù داÙÙ Ù
ÙØ¬Ùد٠تسÙ
Ù [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) ÙØ§Ùت٠تÙ
ÙÙÙØ§ Ù
٠اÙÙØµÙ٠إÙÙ ÙÙ Ø§ÙØ±Ù
ÙØ². ,ØªÙØ¬Ø¯ Ø£ÙØ¶Ùا Ø¯Ø§ÙØ© تسÙ
Ù [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) ÙØ§Ùت٠تÙÙÙ
بإرجاع _ÙÙ_ Ø§ÙØ®ØµØ§Ø¦Øµ Ø¨Ø¯Ø§Ø®Ù ÙØ§Ø¦Ù Ù
عÙ٠بÙ
ا ÙÙÙØ§ Ø§ÙØ®ØµØ§Ø¦Øµ Ø§ÙØªÙ Ù
Ù ÙÙØ¹ Ø§ÙØ±Ù
ز. ÙÙØ°ÙÙ ÙØ¥Ù ÙØ°Ù Ø§ÙØ®ØµØ§Ø¦Øµ ÙÙØ³Øª Ù
Ø®ÙÙØ© باÙÙØ§Ù
Ù. ÙÙÙÙ Ø£Ø¹ÙØ¨ اÙÙ
ÙØªØ¨Ø§Øª ÙØ§ÙØ¯ÙØ§Ù ÙØ§ تستخدÙ
ÙØ°Ù اÙÙØ³Ø§Ø¦Ù.
+=======
+Technically, symbols are not 100% hidden. There is a built-in method [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) that allows us to get all symbols. Also there is a method named [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys of an object including symbolic ones. But most libraries, built-in functions and syntax constructs don't use these methods.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/04-object-basics/09-object-toprimitive/article.md b/1-js/04-object-basics/09-object-toprimitive/article.md
index 2ad596136..30c9e3b11 100644
--- a/1-js/04-object-basics/09-object-toprimitive/article.md
+++ b/1-js/04-object-basics/09-object-toprimitive/article.md
@@ -4,19 +4,56 @@
ÙÙ ÙØ°Ù Ø§ÙØØ§ÙØ©Ø تتØÙ٠اÙÙØ§Ø¦Ùات Ø¥ÙÙ ÙÙÙ
ÙØ±Ø¯ÙØ© تÙÙØ§Ø¦ÙÙØ§Ø Ø«Ù
ÙØªÙ
تÙÙÙØ° ÙØ°Ù Ø§ÙØ¹Ù
ÙÙØ© Ø§ÙØØ³Ø§Ø¨ÙØ©.
+<<<<<<< HEAD
ÙÙ ÙØ³Ù
(تØÙÙÙ Ø§ÙØ£ÙÙØ§Ø¹) رأÙÙØ§ ÙÙÙ ÙÙ
Ù٠تØÙÙ٠اÙÙØµÙص (strings) ÙØ§ÙØ£Ø±ÙØ§Ù
ÙØ§ÙÙÙÙÙ
اÙÙ
ÙØ·ÙÙÙ (booleans) Ø¥ÙÙ ÙÙÙ
ÙØ±Ø¯ÙØ©. ÙÙÙÙÙØ§ ترÙÙØ§ Ù
Ø³Ø§ØØ© ÙØ§Ø±ØºØ© Ù
٠أج٠اÙÙØ§Ø¦Ùات. ÙØ§Ùآ٠بعد أ٠عرÙÙØ§ اÙÙØ«Ùر Ø¹Ù Ø§ÙØ¯Ùا٠(methods) ÙØ§ÙرÙ
ÙØ² (symbols)Ø Ø£ØµØ¨Ø Ø§ÙØ¢Ù Ù
Ù
ÙÙÙØ§ Ø£Ù ÙÙ
ÙØ£ ÙØ°Ù اÙÙ
ساØÙ.
+=======
+JavaScript doesn't allow you to customize how operators work on objects. Unlike some other programming languages, such as Ruby or C++, we can't implement a special object method to handle addition (or other operators).
+
+In case of such operations, objects are auto-converted to primitives, and then the operation is carried out over these primitives and results in a primitive value.
+
+That's an important limitation: the result of `obj1 + obj2` (or another math operation) can't be another object!
+
+E.g. we can't make objects representing vectors or matrices (or achievements or whatever), add them and expect a "summed" object as the result. Such architectural feats are automatically "off the board".
+
+So, because we can't technically do much here, there's no maths with objects in real projects. When it happens, with rare exceptions, it's because of a coding mistake.
+
+In this chapter we'll cover how an object converts to primitive and how to customize it.
+
+We have two purposes:
+
+1. It will allow us to understand what's going on in case of coding mistakes, when such an operation happened accidentally.
+2. There are exceptions, where such operations are possible and look good. E.g. subtracting or comparing dates (`Date` objects). We'll come across them later.
+
+## Conversion rules
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
1. Ù٠اÙÙØ§Ø¦Ùات Ø¹ÙØ¯ تØÙÙÙÙØ§ Ø¥ÙÙ ÙÙÙ
Ù Ù
ÙØ·ÙÙÙ (boolean) ÙØ¥Ù ÙÙÙ
ØªÙØ§ تساÙÙ `true`. ÙØ¨Ø§ÙتاÙÙ ÙØ¥Ù Ø§ÙØªØÙÙÙØ§Øª اÙÙ
ØªØ§ØØ© ÙÙ Ø§ÙØªØÙÙ٠إÙÙ ÙØµ أ٠رÙÙ
.
+<<<<<<< HEAD
2. ÙØØ¯Ø« Ø§ÙØªØÙÙ٠إÙ٠رÙÙ
Ø¹ÙØ¯ Ø·Ø±Ø ÙØ§Ø¦ÙÙ٠أ٠استخداÙ
Ø¯Ø§ÙØ© ØØ³Ø§Ø¨ÙØ©. عÙ٠سبÙ٠اÙÙ
Ø«Ø§ÙØ اÙÙØ§Ø¦Ùات Ù
Ù ÙÙØ¹ `Date` (Ø³ÙØªÙ
شرØÙا ÙÙ ÙØ³Ù
Ø§ÙØªØ§Ø±ÙØ®) ÙÙ
Ù٠طرØÙØ§Ø ÙÙØªÙجة Ø·Ø±Ø `date1 - date2` Ù٠اÙÙØ±Ù بÙÙ Ø§ÙØªØ§Ø±ÙØ®ÙÙ.
3. ÙØ¨Ø§ÙÙØ³Ø¨Ù Ø¥ÙÙ Ø§ÙØªØÙÙ٠إÙÙ ÙØµ -- ÙØ¥ÙÙ ÙØØ¯Ø« عادة Ø¹ÙØ¯ طباعة اÙÙØ§Ø¦Ù باستخداÙ
Ø¯Ø§ÙØ© Ø§ÙØªÙبÙÙ `alert(obj)` ÙØ§ÙØ¯ÙØ§Ù اÙÙ
Ø´Ø§Ø¨ÙØ©.
+=======
+1. There's no conversion to boolean. All objects are `true` in a boolean context, as simple as that. There exist only numeric and string conversions.
+2. The numeric conversion happens when we subtract objects or apply mathematical functions. For instance, `Date` objects (to be covered in the chapter ) can be subtracted, and the result of `date1 - date2` is the time difference between two dates.
+3. As for the string conversion -- it usually happens when we output an object with `alert(obj)` and in similar contexts.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
-## ToPrimitive
+We can implement string and numeric conversion by ourselves, using special object methods.
+<<<<<<< HEAD
ÙÙ
ÙÙÙØ§ Ø§ÙØªØÙÙ
ÙÙ Ø§ÙØªØÙÙ٠إÙÙ ÙØµ أ٠رÙÙ
Ø Ø¨Ø§Ø³ØªØ®Ø¯Ø§Ù
بعض Ø¯ÙØ§Ù اÙÙØ§Ø¦Ùات.
ÙÙØ§Ù Ø«ÙØ§Ø« Ù
ÙØ§ØØ¸Ø§Øª Ù
ختÙÙ٠عÙ٠تØÙÙÙ Ø§ÙØ£ÙÙØ§Ø¹ ÙÙØ·Ù٠عÙÙÙØ§ "hints" ÙØªÙ
Ø°ÙØ±Ùا ÙÙ [اÙÙ
صدر](https://tc39.github.io/ecma262/#sec-toprimitive):
+=======
+Now let's get into technical details, because it's the only way to cover the topic in-depth.
+
+## Hints
+
+How does JavaScript decide which conversion to apply?
+
+There are three variants of type conversion, that happen in various situations. They're called "hints", as described in the [specification](https://tc39.github.io/ecma262/#sec-toprimitive):
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
`"اÙÙØµ"`
@@ -46,9 +83,16 @@
let greater = user1 > user2;
```
+<<<<<<< HEAD
`"Ø§ÙØªØµØ±Ù Ø§ÙØ¥ÙتراضÙ"`
+=======
+ Most built-in mathematical functions also include such conversion.
+
+`"default"`
+: Occurs in rare cases when the operator is "not sure" what type to expect.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
- For instance, binary plus `+` can work both with strings (concatenates them) and numbers (adds them), so both strings and numbers would do. So if a binary plus gets an object as an argument, it uses the `"default"` hint to convert it.
+ For instance, binary plus `+` can work both with strings (concatenates them) and numbers (adds them). So if a binary plus gets an object as an argument, it uses the `"default"` hint to convert it.
عÙ٠سبÙ٠اÙÙ
Ø«Ø§ÙØ Ø§ÙØ¹ÙاÙ
Ù `+` ÙÙ
Ù٠أ٠تعÙ
Ù Ù
ع اÙÙØµÙص (ØÙØ« تÙÙÙ
Ø¨Ø§ÙØ¥Ø¶Ø§ÙÙ) Ø£Ù Ø§ÙØ£Ø±ÙاÙ
(ØÙØ« تÙÙÙ
Ø¨Ø§ÙØ¬Ù
ع)Ø ÙÙØ°ÙÙ ÙØ¥ÙÙ ÙÙ
ÙÙ Ø§ÙØªØÙÙ٠إÙÙ ÙØµÙص Ø£Ù Ø£Ø±ÙØ§Ù
. ÙÙØ°Ù٠إذا Ø§Ø³ØªÙØ¨Ùت Ø¹ÙØ§Ù
Ø© ا٠`+` ÙØ§Ø¦Ùا ÙØ¥ÙÙØ§ تستخدÙ
`"Ø§ÙØªØµØ±Ù Ø§ÙØ¥ÙتراضÙ"`.
@@ -58,12 +102,23 @@
// binary plus uses the "default" hint
let total = obj1 + obj2;
+<<<<<<< HEAD
// obj == number uses the "default" hint
if (user == 1) { ... };
```
+=======
+ The greater and less comparison operators, such as `<` `>`, can work with both strings and numbers too. Still, they use the `"number"` hint, not `"default"`. That's for historical reasons.
+
+In practice though, things are a bit simpler.
+
+All built-in objects except for one case (`Date` object, we'll learn it later) implement `"default"` conversion the same way as `"number"`. And we probably should do the same.
+
+Still, it's important to know about all 3 hints, soon we'll see why.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
اÙÙ
ÙØ§Ø±Ù٠باستخداÙ
Ø¹ÙØ§Ù
ات Ø§ÙØ£Ùبر Ù
Ù Ø£Ù Ø§ÙØ£ØµØºØ± Ù
Ù Ù
ث٠`<` `>`Ø ÙÙ
ÙÙÙØ§ Ø§ÙØªØ¹Ø§Ù
Ù Ù
ع Ø§ÙØ£Ø±ÙاÙ
ÙØ§ÙÙØµÙص Ø£ÙØ¶Ø§ ÙÙÙÙÙØ§ Ù
ع ذÙ٠تستخدÙ
Ø§ÙØªØÙÙ٠إÙ٠رÙÙ
ÙÙÙØ³ Ø§ÙØ·Ø±ÙÙÙ Ø§ÙØ§ÙتراضÙÙØ ÙÙØ°Ø§ ÙØ£Ø³Ø¨Ø§Ø¨ Ù
تأصÙÙ historical reasons.
+<<<<<<< HEAD
ÙØ§ ÙØØªØ§Ø¬ Ø¥ÙÙ ØªØ°ÙØ± ÙÙ ÙØ°Ù Ø§ÙØªÙاصÙÙ Ø§ÙØºØ±ÙØ¨Ù ÙØ£Ù Ù٠اÙÙØ§Ø¦Ùات اÙÙ
ÙØ¬Ùد٠عدا (`Date` ÙØ§ÙØ°Ù Ø³ÙØªÙ
شرØÙ ÙØ±Ùبا) ÙØªÙ
تØÙÙÙÙØ§ باستخداÙ
`"Ø§ÙØ·Ø±ÙÙÙ Ø§ÙØ¥ÙتراضÙÙ"` Ù
ث٠طرÙÙØ© Ø§ÙØªØÙÙ٠إÙ٠رÙÙ
.
```smart header="ÙØ§ ÙÙØ¬Ø¯ Ø§ÙØªØÙÙ٠إÙÙ `\"اÙÙÙÙ
اÙÙ
ÙØ·ÙÙÙ\"`"
@@ -80,6 +135,13 @@ if (user == 1) { ... };
- استخداÙ
`obj.toString()` Ù `obj.valueOf()`Ø Ø£ÙÙÙ
Ù
ÙØ¬Ùد.
3. ØºÙØ± ذÙÙØ إذا ÙØ§Ùت Ø§ÙØ·Ø±ÙÙÙ ÙÙ `"Ø§ÙØ·Ø±ÙÙÙ Ø§ÙØ¥ÙتراضÙÙ"` Ø£Ù `"Ø§ÙØ±ÙÙ
"`
- استخداÙ
`obj.valueOf()` Ù `obj.toString()`Ø Ø£ÙÙÙ
Ù
ÙØ¬Ùد.
+=======
+1. Call `obj[Symbol.toPrimitive](hint)` - the method with the symbolic key `Symbol.toPrimitive` (system symbol), if such method exists,
+2. Otherwise if hint is `"string"`
+ - try calling `obj.toString()` or `obj.valueOf()`, whatever exists.
+3. Otherwise if hint is `"number"` or `"default"`
+ - try calling `obj.valueOf()` or `obj.toString()`, whatever exists.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## Symbol.toPrimitive
@@ -87,12 +149,19 @@ if (user == 1) { ... };
```js
obj[Symbol.toPrimitive] = function(hint) {
- // must return a primitive value
+ // here goes the code to convert this object to a primitive
+ // it must return a primitive value
// hint = one of "string", "number", "default"
};
````
+<<<<<<< HEAD
عÙ٠سبÙ٠اÙÙ
ثاÙ, ÙØ·Ø¨Ù ÙØ°Ù Ø§ÙØ·Ø±ÙÙ٠اÙÙØ§Ø¦Ù `user`:
+=======
+If the method `Symbol.toPrimitive` exists, it's used for all hints, and no more methods are needed.
+
+For instance, here `user` object implements it:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let user = {
@@ -111,6 +180,7 @@ alert(+user); // hint: number -> 1000
alert(user + 500); // hint: default -> 1500
```
+<<<<<<< HEAD
ÙÙ
ا ÙØ±Ù Ù
٠اÙÙ
Ø«Ø§ÙØ ÙØ¥Ù اÙÙØ§Ø¦Ù `user` ÙØªØÙ٠إÙÙ ÙØµ Ù
عبر أ٠إÙÙ ÙÙ
اÙÙÙÙØ¯ Ø¨ÙØ§Ø¡Ùا عÙ٠طرÙÙØ© Ø§ÙØªØÙÙÙ ÙÙØ³Ùا. ÙØ¥Ù Ø§ÙØ·Ø±ÙÙÙ `user[Symbol.toPrimitive]` تتعاÙ
Ù Ù
ع ÙÙ Ø·Ø±Ù Ø§ÙØªØÙÙÙ.
## toString/valueOf
@@ -123,6 +193,20 @@ alert(user + 500); // hint: default -> 1500
- `valueOf -> toString` ØºÙØ± ذÙÙ.
ÙØ°Ù Ø§ÙØ¯ÙØ§Ù ÙØ§Ø¨Ø¯ أ٠تÙÙÙ
بإرجاع ÙÙÙ
Ù ÙØ±Ø¯ÙØ©. ÙØ¥Ø°Ø§ ÙØ§Ù
ت ÙØ§ØªØ§Ù Ø§ÙØ¯Ø§Ùتا٠بإرجاع ÙØ§Ø¦Ù ÙØ³ÙتÙ
تجاÙÙÙ.
+=======
+As we can see from the code, `user` becomes a self-descriptive string or a money amount, depending on the conversion. The single method `user[Symbol.toPrimitive]` handles all conversion cases.
+
+## toString/valueOf
+
+If there's no `Symbol.toPrimitive` then JavaScript tries to find methods `toString` and `valueOf`:
+
+- For the `"string"` hint: call `toString` method, and if it doesn't exist or if it returns an object instead of a primitive value, then call `valueOf` (so `toString` has the priority for string conversions).
+- For other hints: call `valueOf`, and if it doesn't exist or if it returns an object instead of a primitive value, then call `toString` (so `valueOf` has the priority for maths).
+
+Methods `toString` and `valueOf` come from ancient times. They are not symbols (symbols did not exist that long ago), but rather "regular" string-named methods. They provide an alternative "old-style" way to implement the conversion.
+
+These methods must return a primitive value. If `toString` or `valueOf` returns an object, then it's ignored (same as if there were no method).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø£Ù ÙØ§Ø¦Ù ÙÙ
تÙÙ Ø§ÙØªØ±Ø§Ø¶Ùا Ø§ÙØ¯Ø§ÙتÙÙ `toString` Ù `valueOf`:
@@ -140,9 +224,15 @@ alert(user.valueOf() === user); // true
ÙØ°Ù٠إذا ØØ§ÙÙÙØ§ Ø£Ù ÙØ³ØªØ®Ø¯Ù
اÙÙØ§Ø¦Ù ÙÙØµØ ÙÙ
ا ÙÙ ØØ§ÙØ© استخداÙ
Ø§ÙØ¯Ø§Ù٠اÙÙØµÙÙ `alert` Ø³ÙØ±Ù بشÙÙ Ø§ÙØªØ±Ø§Ø¶Ù `[object object]`.
+<<<<<<< HEAD
Ø§ÙØ¯Ø§ÙÙ `valueOf` تÙ
Ø°ÙØ±Ùا ÙÙØ§ ÙÙØ· ÙØ¥ÙÙ
ا٠اÙÙ
عÙÙÙ
ات ÙÙØªØ¬Ùب Ø£Ù Ø§ÙØªØ¨Ø§Ø³. ÙÙÙ
ا ØªØ±Ù ÙØ¥Ù ÙØ°Ù Ø§ÙØ¯Ø§Ù٠تÙÙÙ
بإرجاع اÙÙØ§Ø¦Ù ÙÙØ³Ù ÙØ¨Ø§ÙتاÙÙ ÙØªÙ
تجاÙÙÙ. ÙØ§ تسأ٠ÙÙ
اذا ÙÙØ°Ø§ ÙØ£Ø³Ø¨Ø§Ø¨ Ù
تأصÙÙ historical reasons. ÙÙØ°ÙÙ ÙÙ
ÙÙÙØ§ اعتبار Ø£ÙÙØ§ ØºÙØ± Ù
ÙØ¬ÙدÙ.
ÙÙØ§ ÙÙÙÙ
باستخداÙ
ÙØ°Ù Ø§ÙØ¯ÙاÙ.
+=======
+The default `valueOf` is mentioned here only for the sake of completeness, to avoid any confusion. As you can see, it returns the object itself, and so is ignored. Don't ask me why, that's for historical reasons. So we can assume it doesn't exist.
+
+Let's implement these methods to customize the conversion.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
عÙ٠سبÙ٠اÙÙ
Ø«Ø§ÙØ ÙØ¥Ù اÙÙØ§Ø¦Ù `user` ÙÙØ§ ÙÙÙÙ
بÙÙØ³ Ø§ÙØªØµØ±Ù Ø£Ø¹ÙØ§Ù Ø¹ÙØ¯ استخداÙ
Ø®ÙÙØ· Ù
Ù `toString` Ù `valueOf` بدÙÙØ§ Ù
Ù `Symbol.toPrimitive`:
@@ -186,11 +276,19 @@ alert(user + 500); // toString -> John500
ÙÙ ØØ§ÙØ© ØºÙØ§Ø¨ `Symbol.toPrimitive` Ù `valueOf` ÙØ¥Ù `toString` ستÙÙÙ
Ø¨Ø§ÙØªØ¹Ø§Ù
Ù Ù
ع ÙÙ ØØ§Ùات Ø§ÙØªØÙÙ٠إÙÙ ÙÙÙ
ÙØ±Ø¯ÙÙ.
+<<<<<<< HEAD
## Ø£ÙÙØ§Ø¹ اÙÙÙÙ
اÙÙ
سترجعÙ
+=======
+### A conversion can return any primitive type
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ§Ù شئ Ù
ÙÙ
ÙØ¬Ø¨ أ٠تعرÙÙ ÙÙ٠أ٠ÙÙ Ø·Ø±Ù Ø§ÙØªØÙÙ٠إÙÙ ÙÙÙ
Ù
ÙØ±Ø¯Ù ÙØ§ ÙØ¬Ø¨ Ø¨Ø§ÙØ¶Ø±Ùر٠أ٠تÙÙÙ
بإرجاع ÙÙØ³ ÙÙØ¹ اÙÙÙÙ
٠اÙÙ
ÙØ±Ø¯Ù اÙÙ
ØÙÙÙÙ٠إÙÙÙ.
+<<<<<<< HEAD
ÙÙØ§ ÙÙØ¬Ø¯ ضÙ
اÙ٠إذا ÙØ§Ùت `toString` ستÙÙÙ
بإرجاع ÙØµ Ø¨Ø§ÙØªØØ¯Ùد Ø£Ù ØØªÙ `Symbol.toPrimitive` ستÙÙÙ
بإرجاع رÙÙ
Ù٠طرÙÙØ© `"Ø§ÙØ±ÙÙ
"`.
+=======
+There is no control whether `toString` returns exactly a string, or whether `Symbol.toPrimitive` method returns a number for the hint `"number"`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø§ÙØ£Ù
ر اÙÙØÙØ¯ Ø§ÙØ°Ù ÙÙ
Ù٠ضÙ
اÙÙ ÙØ§ÙØ¥ÙØ²Ø§Ù
Ù ÙÙ Ø£Ù ÙØ°Ù Ø§ÙØ¯ÙØ§Ù ÙØ¬Ø¨ أ٠تÙÙÙ
بإرجاع ÙÙ
Ø© Ù
ÙØ±Ø¯Ø© ÙØ§ ÙØ§Ø¦ÙÙØ§.
@@ -199,14 +297,24 @@ alert(user + 500); // toString -> John500
`toString` or `valueOf`
ÙØ§Ù
ت بإرجاع ÙØ§Ø¦ÙØ ÙÙØ§ ÙÙØ¬Ø¯ خطأ ÙØ¸ÙØ±Ø Ø¨Ù ÙØªÙ
تجا٠اÙÙØªÙج٠ÙÙØ· ÙØ£Ù Ø´ÙØ¦Ùا ÙÙ
ÙÙÙ. ÙØ°ÙÙ ÙØ£ÙÙ Ù٠اÙÙ
اض٠ÙÙ
ÙÙÙ ÙÙØ§Ù Ù
ÙÙÙÙ
Ø¬ÙØ¯ ÙÙØ®Ø·Ø£ ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت.
+<<<<<<< HEAD
عÙ٠اÙÙÙÙØ¶Ø ÙØ¥Ù `Symbol.toPrimitive` *ÙØ¬Ø¨* أ٠تÙÙÙ
بإرجاع ÙÙÙ
Ø© Ù
ÙØ±Ø¯ÙØ ÙØ¥Ùا سÙÙÙÙ ÙÙØ§Ù خطأ.
+=======
+In contrast, `Symbol.toPrimitive` is stricter, it *must* return a primitive, otherwise there will be an error.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
## Ø§ÙØªØÙÙÙØ§Øª Ø§ÙØ¥Ø¶Ø§ÙÙÙ
ÙÙ
ا ÙØ¹Ø±Ù باÙÙØ¹Ù أ٠اÙÙØ«Ùر Ù
Ù Ø§ÙØ¹ÙاÙ
ات ÙØ§ÙØ¯ÙØ§Ù تÙÙÙ
بتØÙÙÙ Ø§ÙØ£ÙÙØ§Ø¹, Ù
ثا٠عÙ٠ذÙÙ Ø¹ÙØ§Ù
Ø© `*` تÙÙÙ
بتØÙÙÙ Ø§ÙØ¹Ø§Ù
ÙÙ٠إÙÙ Ø£Ø±ÙØ§Ù
.
+<<<<<<< HEAD
إذا استخدÙ
ÙØ§ ÙØ§Ø¦ÙÙÙ ÙØ¹Ù
ÙÙÙ Ø±ÙØ§Ø¶ÙÙÙ ÙØ³ÙÙÙÙ ÙÙØ§Ù Ù
رØÙتÙÙ:
+=======
+If we pass an object as an argument, then there are two stages of calculations:
+1. The object is converted to a primitive (using the rules described above).
+2. If necessary for further calculations, the resulting primitive is also converted.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
1. تØÙÙ٠إÙ٠اÙÙØ§Ø¦Ù Ø¥ÙÙ ÙÙÙ
Ù Ù
ÙØ±Ø¯Ø©.
2. إذا ÙØ§Ùت ÙØªÙجة Ø§ÙØªØÙÙÙ ÙÙØ³Øª Ù
٠اÙÙÙØ¹ Ø§ÙØµØÙØ ÙØ³ÙتÙ
تØÙÙÙÙØ§.
@@ -236,23 +344,33 @@ let obj = {
},
};
-alert(obj + 2); // 22 ("2" + 2), conversion to primitive returned a string => concatenation
+alert(obj + 2); // "22" ("2" + 2), conversion to primitive returned a string => concatenation
```
## اÙÙ
ÙØ®Øµ
Ø§ÙØªØÙÙÙ Ù
Ù ÙØ§Ø¦Ù Ø¥ÙÙ ÙÙÙ
Ø© Ù
ÙØ±Ø¯Ø© ÙØØ¯Ø« تÙÙØ§Ø¦Ùا ع٠طرÙ٠اÙÙØ«Ùر Ù
Ù Ø§ÙØ¯Ùا٠اÙÙ
ÙØ¬Ùد٠باÙÙØ¹Ù ÙØ§ÙعÙ
ÙÙØ§Øª Ø§ÙØªÙ ØªÙØ¬Ø±Ù ÙØ§Ùت٠تعÙ
Ù ÙÙØ· عÙÙ ÙÙÙ
Ù
ÙØ±Ø¯Ø© ÙÙÙØ³ ÙØ§Ø¦Ùات.
+<<<<<<< HEAD
ÙÙØ§Ù 3 Ø£ÙÙØ§Ø¹ Ù
Ù Ø·Ø±Ù Ø§ÙØªØÙÙÙ:
- `"اÙÙØµ"` (ÙÙØØ¯Ø« ذÙÙ Ø¹ÙØ¯ استخداÙ
Ø¯Ø§ÙØ© Ø§ÙØªÙبÙÙ `alert` ÙØ§Ùت٠تتÙÙØ¹ ÙØµÙا).
- `"Ø§ÙØ±ÙÙ
"` (ÙÙ Ø§ÙØ¹Ù
ÙÙØ§Øª Ø§ÙØØ³Ø§Ø¨ÙÙ).
- `"Ø§ÙØ·Ø±ÙÙØ© Ø§ÙØ¥ÙتراضÙÙ"` (Ù٠بعض Ø§ÙØ¹Ù
ÙÙØ§Øª).
+=======
+There are 3 types (hints) of it:
+- `"string"` (for `alert` and other operations that need a string)
+- `"number"` (for maths)
+- `"default"` (few operators, usually objects implement it the same way as `"number"`)
+
+The specification describes explicitly which operator uses which hint.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ¶Ø اÙÙ
صدر أ٠عÙ
ÙÙØ© تستخدÙ
أ٠طرÙÙÙ. ÙÙÙØ§Ù اÙÙÙÙÙ Ù
Ù Ø§ÙØ¹Ù
ÙÙØ§Øª Ø§ÙØªÙ
"ÙØ§ تعÙÙ
Ù
ا ÙÙØ¹ Ø§ÙØ¹Ø§Ù
Ù Ø§ÙØ°Ù Ø³ØªØ³ØªÙØ¨ÙÙ"
ÙØªØ³ØªØ®Ø¯Ù
`"Ø§ÙØ·Ø±ÙÙÙ Ø§ÙØ¥ÙتراضÙÙ"`. ÙØ¹Ø§Ø¯Ø©Ù Ù
ا ÙØªÙ
استخداÙ
`"Ø§ÙØ·Ø±ÙÙØ© Ø§ÙØ¥ÙتراضÙÙ"` Ù
ع اÙÙØ§Ø¦Ùات اÙÙ
ÙØ¬Ùد٠باÙÙØ¹Ù ÙÙ
ا ÙØªÙ
Ø§ÙØªØ¹Ø§Ù
Ù Ù
ع `"Ø§ÙØ£Ø±ÙاÙ
"`, ÙÙØ°Ù٠عÙ
ÙÙØ§ ÙØ¥Ù Ø§ÙØ·Ø±ÙÙØªÙÙ Ø§ÙØ£Ø®ÙرتÙÙ ÙÙ
Ù٠ضÙ
ÙÙ
ا Ù
Ø¹ÙØ§.
+<<<<<<< HEAD
تتÙ
طرÙÙØ© Ø§ÙØªØÙÙÙ ÙØ§ÙآتÙ:
1. استدعاء Ø§ÙØ¯Ø§ÙÙ `obj[Symbol.toPrimitive](hint)` ÙÙ ØØ§ÙØ© ÙØ¬ÙØ¯ÙØ§,
@@ -262,3 +380,14 @@ alert(obj + 2); // 22 ("2" + 2), conversion to primitive returned a string => co
- استخداÙ
`obj.valueOf()` Ø£Ù `obj.toString()` ÙÙ ØØ§ÙØ© ÙØ¬Ùد Ø£Ù Ù
ÙÙÙ
.
ÙÙÙÙ٠عÙ
ÙÙÙØ§ استخداÙ
`obj.toString()` ÙÙÙ Ø§ÙØªØÙÙÙØ§Øª ÙØ§Ùت٠تÙÙÙ
بإرجاع ÙÙÙ
Ø© ÙÙ
ÙÙ ÙØ±Ø§Ø¦ØªÙا Ù
Ù Ø£Ø¬Ù Ø§ÙØ·Ø¨Ø§Ø¹Ø© Ø£Ù Ø§ÙØ¨ØØ« Ø¹Ù Ø§ÙØ£Ø®Ø·Ø§Ø¡.
+=======
+1. Call `obj[Symbol.toPrimitive](hint)` if the method exists,
+2. Otherwise if hint is `"string"`
+ - try calling `obj.toString()` or `obj.valueOf()`, whatever exists.
+3. Otherwise if hint is `"number"` or `"default"`
+ - try calling `obj.valueOf()` or `obj.toString()`, whatever exists.
+
+All these methods must return a primitive to work (if defined).
+
+In practice, it's often enough to implement only `obj.toString()` as a "catch-all" method for string conversions that should return a "human-readable" representation of an object, for logging or debugging purposes.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md b/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md
index 614d98912..2adddfa7a 100644
--- a/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md
+++ b/1-js/05-data-types/01-primitives-methods/1-string-new-property/task.md
@@ -15,5 +15,9 @@ str.test = 5;
alert(str.test);
```
+<<<<<<< HEAD
ÙÙÙ ØªØ¹ØªÙØ¯ Ø£ÙÙØ§ Ø³ØªÙØ¬ØØ
Ù
اذا Ø³ÙØªØ¶ØØ
+=======
+What do you think, will it work? What will be shown?
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/05-data-types/01-primitives-methods/article.md b/1-js/05-data-types/01-primitives-methods/article.md
index 7c7671d2d..03b41dfb2 100644
--- a/1-js/05-data-types/01-primitives-methods/article.md
+++ b/1-js/05-data-types/01-primitives-methods/article.md
@@ -40,8 +40,13 @@ Objects "اثÙÙ" Ù
Ù Ø§ÙØ£Ø³Ø§ÙÙØ¨ Ø§ÙØ¨Ø¯Ø§Ø¦ÙØ©. ÙÙÙ ØªØªØ·ÙØ¨ Ù
ÙÙØ§ Ø§ÙØªÙØ§ÙØ¶ Ø§ÙØ°Ù ÙØ§Ø¬Ù ØµØ§ÙØ¹ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت:
+<<<<<<< HEAD
- ÙÙØ§Ù Ø§ÙØ¹Ø¯Ùد Ù
Ù Ø§ÙØ£Ø´Ùاء Ø§ÙØªÙ ÙÙ
Ù٠أ٠ÙÙØ¹ÙÙØ§ Ø§ÙØ´Ø®Øµ Ø¨Ø§ÙØ£Ø³ÙÙØ¨ Ø§ÙØ¨Ø¯Ø§Ø¦Ù Ù
ث٠string Ø£Ù number. سÙÙÙÙ Ù
Ù Ø§ÙØ±Ø§Ø¦Ø¹ استخداÙ
ÙÙ
ÙØ§ methods.
- Ø§ÙØ£Ø³Ø§ÙÙØ¨ Ø§ÙØ¨Ø¯Ø§Ø¦ÙØ© ÙØ¬Ø¨ أ٠تÙÙÙ Ø³Ø±ÙØ¹Ø© ÙØ®ÙÙÙØ© Ø¨ÙØ¯Ø± Ø§ÙØ¥Ù
ÙØ§Ù.
+=======
+- There are many things one would want to do with a primitive, like a string or a number. It would be great to access them using methods.
+- Primitives must be as fast and lightweight as possible.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¥Ù Ø§ÙØÙ ÙØ¨Ø¯Ù ØºØ±ÙØ¨Ø§ بعض Ø§ÙØ´ÙØ¡Ø ÙÙÙÙ ÙØ§ ÙÙ:
@@ -49,7 +54,11 @@ Objects "اثÙÙ" Ù
Ù Ø§ÙØ£Ø³Ø§ÙÙØ¨ Ø§ÙØ¨Ø¯Ø§Ø¦ÙØ©. ÙÙÙ ØªØªØ·ÙØ¨ Ù
2. تسÙ
Ø Ø§ÙÙØºØ© باÙÙØµÙ٠اÙ٠ا٠methods Ù Ø§ÙØ®ØµØ§Ø¦Øµ Ø§ÙØ®Ø§ØµØ© ب strings, numbers, booleans Ù symbols.
3. ÙÙÙÙ ÙØ¹Ù
٠ذÙÙØ ÙØªÙ
Ø¥ÙØ´Ø§Ø¡ "object wrapper" خاص ÙÙÙØ± اÙÙØ¸Ø§Ø¦Ù Ø§ÙØ¥Ø¶Ø§ÙÙØ©Ø Ø«Ù
ÙØªÙ
تدÙ
ÙØ±Ù.
+<<<<<<< HEAD
ا٠"object wrappers" تختÙÙ ÙÙÙ ÙÙØ¹ بدائ٠٠تدعÙ: `String`, `Number`, `Boolean` Ù `Symbol`. ÙØ¨Ø§ÙتاÙÙØ ÙØ¥ÙÙØ§ تÙÙØ± Ù
جÙ
ÙØ¹Ø§Øª Ù
ختÙÙØ© Ù
Ù methods.
+=======
+The "object wrappers" are different for each primitive type and are called: `String`, `Number`, `Boolean`, `Symbol` and `BigInt`. Thus, they provide different sets of methods.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
عÙ٠سبÙ٠اÙÙ
ثاÙ
, ÙÙØ§ÙÙ a string method [()str.toUpperCase](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase) Ø§ÙØªÙ ترجع capitalized `str`.
@@ -106,9 +115,16 @@ if (zero) { // zero is true, because it's an object
}
```
+<<<<<<< HEAD
Ù
Ù ÙØ§ØÙØ© أخرÙ, استخداÙ
ÙÙØ³ ا٠functions `String/Number/Boolean` بدÙÙ `new` ÙÙ Ø´ÙØ¡ سÙÙÙÙ
Ù Ù
ÙÙØ¯. ÙØÙÙÙÙ ÙÙÙ
Ø© Ø¥Ù٠اÙÙÙØ¹ اÙÙ
ÙØ§Ø¨Ù: Ø¥ÙÙ a string, a number, or a boolean (primitive - ÙÙØ¹ بدائÙ).
عÙ٠سبÙ٠اÙÙ
ثاÙ, ÙØ°Ø§ صØÙØ ØªÙ
اÙ
ا:
+=======
+On the other hand, using the same functions `String/Number/Boolean` without `new` is totally fine and useful thing. They convert a value to the corresponding type: to a string, a number, or a boolean (primitive).
+
+For example, this is entirely valid:
+
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
let num = Number("123"); // convert a string to number
```
diff --git a/1-js/05-data-types/02-number/2-why-rounded-down/solution.md b/1-js/05-data-types/02-number/2-why-rounded-down/solution.md
index 2d6e8f487..abf468d43 100644
--- a/1-js/05-data-types/02-number/2-why-rounded-down/solution.md
+++ b/1-js/05-data-types/02-number/2-why-rounded-down/solution.md
@@ -25,6 +25,10 @@ alert( (6.35 * 10).toFixed(20) ); // 63.50000000000000000000
```js run
+<<<<<<< HEAD
alert( Math.round(6.35 * 10) / 10); // 6.35 -> 63.5 -> 64(Ù
ÙØ±Ø¨) -> 6.4
+=======
+alert( Math.round(6.35 * 10) / 10 ); // 6.35 -> 63.5 -> 64(rounded) -> 6.4
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
diff --git a/1-js/05-data-types/02-number/article.md b/1-js/05-data-types/02-number/article.md
index 0198ff2ee..d6f921a9a 100644
--- a/1-js/05-data-types/02-number/article.md
+++ b/1-js/05-data-types/02-number/article.md
@@ -2,10 +2,16 @@
ÙÙØ¬Ø¯ ÙÙØ¹Ø§Ù Ù
Ù Ø§ÙØ£Ø¹Ø¯Ø§Ø¯ ÙÙ JavaScript:
+<<<<<<< HEAD
1. أعداد Ø¹Ø§Ø¯ÙØ© تخزÙÙÙ Ø¨ØµÙØºØ© 64-بت [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision)Ø ØªÙØ¹Ø±Ù Ø£ÙØ¶Ùا ب "Ø§ÙØ£Ø¹Ø¯Ø§Ø¯ Ø§ÙØ¹Ø´Ø±ÙØ© Ù
Ø¶Ø§Ø¹ÙØ© Ø§ÙØ¯ÙØ©" (double precision floating point numbers). ÙØ°Ø§ اÙÙÙØ¹ ÙÙ Ù
ا Ø³ÙØ³ØªØ¹ÙÙ
Ù Ø£ØºÙØ¨ اÙÙÙØª ÙØ³ÙØ³ÙØ· عÙÙÙ Ø§ÙØ¶ÙØ¡ ÙÙ ÙØ°Ø§ اÙÙØµÙ.
2. أعداد صØÙØØ© ÙØ¨Ùرة (BigInt numbers) تÙ
Ø«ÙÙÙ Ø¹Ø¯Ø¯ÙØ§ صØÙØÙا Ù
ØªØºÙØ± Ø§ÙØØ¬Ù
Ø Ø¥Ø° ÙØ¯ ÙÙØ¬Ø£ Ø¥ÙÙÙØ§ Ø£ØÙاÙÙØ§ ÙØ£Ù اÙÙÙØ¹ Ø§ÙØ³Ø§Ø¨Ù ÙØ§ ÙÙ
ÙÙ Ø£Ù ÙØªØ¬Ø§Ùز اÙÙÙÙ
Ø© 2^53 أ٠أ٠تÙ٠ع٠-2^53Ø ÙØ³Ùخصص ÙÙØ°Ø§ اÙÙÙØ¹ ÙØµÙÙØ§ Ø®Ø§ØµÙØ§ Ø¨Ù ÙØ¸Ø±Ùا ÙÙØØ§Ø¬Ø© Ø¥ÙÙÙ ÙÙ ØØ§Ùات خاصة.
ØØ§ÙÙÙØ§Ø ÙÙÙØªÙسع ع٠Ù
ا ÙØ¹Ø±Ù٠عÙÙØ§Ø ÙÙÙØªÙ٠إÙÙ Ø§ÙØØ¯ÙØ« ع٠اÙÙÙØ¹ Ø§ÙØ£ÙÙØ Ø§ÙØ£Ø¹Ø¯Ø§Ø¯ Ø§ÙØ¹Ø§Ø¯ÙØ©.
+=======
+1. Regular numbers in JavaScript are stored in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754), also known as "double precision floating point numbers". These are numbers that we're using most of the time, and we'll talk about them in this chapter.
+
+2. BigInt numbers represent integers of arbitrary length. They are sometimes needed because a regular integer number can't safely exceed (253-1) or be less than -(253-1), as we mentioned earlier in the chapter . As bigints are used in a few special areas, we devote them to a special chapter .
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## طر٠أخر٠ÙÙØªØ§Ø¨Ø© عدد
@@ -21,7 +27,7 @@ We also can use underscore `_` as the separator:
let billion = 1_000_000_000;
```
-Here the underscore `_` plays the role of the "syntactic sugar", it makes the number more readable. The JavaScript engine simply ignores `_` between digits, so it's exactly the same one billion as above.
+Here the underscore `_` plays the role of the "[syntactic sugar](https://en.wikipedia.org/wiki/Syntactic_sugar)", it makes the number more readable. The JavaScript engine simply ignores `_` between digits, so it's exactly the same one billion as above.
In real life though, we try to avoid writing long sequences of zeroes. We're too lazy for that. We'll try to write something like `"1bn"` for a billion or `"7.3bn"` for 7 billion 300 million. The same is true for most large numbers.
@@ -35,6 +41,7 @@ let billion = 1e9; // بÙÙÙÙØ ØØ±ÙÙÙØ§: 1 ÙØ¬Ø§Ùب٠9 Ø£ØµÙØ§Ø±
In other words, `e` multiplies the number by `1` with the given zeroes count.
```js
+<<<<<<< HEAD
1e3 = 1 * 1000 // e3 means *1000
1.23e6 = 1.23 * 1000000 // e6 means *1000000
````
@@ -52,15 +59,46 @@ let ms = 1e-6; // ستة Ø£ØµÙØ§Ø± عÙÙ ÙØ³Ø§Ø± 1
```
Ø¥Ù ÙÙ
ÙØ§ بعد Ø§ÙØ£ØµÙار ÙÙ `0.000001`Ø Ø³ÙØ¬Ø¯ Ø¹Ø¯Ø¯ÙØ§ 6. ÙØ°Ø§ ÙÙÙÙ Ø§ÙØ±ÙÙ
`1e-6`.
+=======
+1e3 === 1 * 1000; // e3 means *1000
+1.23e6 === 1.23 * 1000000; // e6 means *1000000
+```
+
+Now let's write something very small. Say, 1 microsecond (one-millionth of a second):
+
+```js
+let mÑs = 0.000001;
+```
+
+Just like before, using `"e"` can help. If we'd like to avoid writing the zeroes explicitly, we could write the same as:
+
+```js
+let mcs = 1e-6; // five zeroes to the left from 1
+```
+
+If we count the zeroes in `0.000001`, there are 6 of them. So naturally it's `1e-6`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
بÙ
عÙÙ Ø¢Ø®Ø±Ø ÙØ¬Ùد رÙÙ
Ø³Ø§ÙØ¨ بعد `"e"` ÙØ¹Ù٠اÙÙØ³Ù
Ø© عÙÙ 1 Ù
ØªØ¨ÙØ¹Ùا Ø¨ÙØ¹Ø¯Ø¯ Ø§ÙØ£ØµÙار اÙÙ
عطÙ:
+<<<<<<< HEAD
```
// -3 باÙÙØ³Ù
Ø© عÙÙ 1 Ù
ØªØ¨ÙØ¹Ùا ب 3 Ø£ØµÙØ§Ø±
1e-3 = 1 / 1000 (=0.001)
// -6 باÙÙØ³Ù
Ø© عÙÙ 1 Ù
ØªØ¨ÙØ¹Ùا ب 6 Ø£ØµÙØ§Ø±
1.23e-6 = 1.23 / 1000000 (=0.00000123)
+=======
+```js
+// -3 divides by 1 with 3 zeroes
+1e-3 === 1 / 1000; // 0.001
+
+// -6 divides by 1 with 6 zeroes
+1.23e-6 === 1.23 / 1000000; // 0.00000123
+
+// an example with a bigger number
+1234e-2 === 1234 / 100; // 12.34, decimal point moves 2 times
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
### Ø§ÙØ£Ø¹Ø¯Ø§Ø¯ Ø§ÙØ³Øª Ø¹Ø´Ø±ÙØ©Ø ÙØ§ÙØ«ÙØ§Ø¦ÙØ© ÙØ§ÙØ«Ù
اÙÙØ©
@@ -94,16 +132,38 @@ alert( num.toString(16) ); // ff
alert( num.toString(2) ); // 11111111
```
+<<<<<<< HEAD
ÙÙ
Ù٠أ٠تختÙÙ ÙÙÙ
Ø© `base` Ù
Ù `2` ØØªÙ `36`Ø ÙØ§ÙÙÙÙ
Ø© Ø§ÙØ§ÙØªØ±Ø§Ø¶ÙØ© ÙÙ `10`.
+=======
+The `base` can vary from `2` to `36`. By default, it's `10`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ØØ§Ùات Ø§ÙØ§Ø³ØªØ®Ø¯Ø§Ù
Ø§ÙØ´Ø§Ø¦Ø¹Ø©:
+<<<<<<< HEAD
- `base=16`: تستخدÙ
ÙÙØ£ÙÙØ§Ù Ø§ÙØ³Øª Ø¹Ø´Ø±ÙØ©Ø ÙØªØ´ÙÙØ± Ø§ÙØ£ØØ±ÙÙ ÙØºÙØ±ÙØ§Ø ÙØ¯ تØÙÙ Ø§ÙØ®Ø§Ùات Ø§ÙØ£Ø±ÙاÙ
`0..9` Ø£Ù Ø§ÙØ£ØØ±Ù `A..F`.
- `base=2`: ÙØ³ØªØ®Ø¯Ù
Ø¨ÙØ«Ø±Ø© Ù٠تصØÙØ Ø§ÙØ¹Ù
ÙÙØ§Øª Ø§ÙØ¯ÙÙÙØ©Ø ÙÙ
ÙÙ Ø£Ù ÙØÙÙ Ø§ÙØ±ÙÙ
ÙÙ `0` Ø£Ù `1`.
- `base=36`: ÙÙ Ø§ÙØØ¯ Ø§ÙØ£Ø¹ÙÙØ ÙÙ
ÙÙ Ø£Ù ÙØÙÙ Ø§ÙØ£Ø±ÙاÙ
`0..9` Ø£Ù Ø§ÙØ£ØØ±ÙÙ `A..Z`. ÙÙ
Ù٠استخداÙ
جÙ
ÙØ¹ Ø§ÙØ£ØØ±Ù اÙÙØ§ØªÙÙÙØ© ÙØªÙ
Ø«Ù٠عدد. ÙØ¯ ÙØ¨Ø¯Ù Ø£Ù
Ø±ÙØ§ Ù
Ù
ØªØ¹ÙØ§ ÙÙÙ ÙÙÙÙ Ù
ÙÙØ¯Ùا ÙÙ ØØ§Ù Ø§ØØªØ¬Ùا ÙØªØÙÙÙ Ù
عر٠عدد٠طÙÙ٠إÙ٠عدد Ø£ÙØµØ±Ø Ù
Ø«ÙÙØ§Ø ÙØªÙØµÙØ± رابط url. ÙÙ
Ù٠تÙ
Ø«ÙÙ٠باÙÙØ¸Ø§Ù
Ø§ÙØ¹Ø¯Ø¯Ù Ø°Ù Ø§ÙØ£Ø³Ø§Ø³ `36`:
```
alert( 123456..toString(36) ); // 2n9c
+=======
+- **base=16** is used for hex colors, character encodings etc, digits can be `0..9` or `A..F`.
+- **base=2** is mostly for debugging bitwise operations, digits can be `0` or `1`.
+- **base=36** is the maximum, digits can be `0..9` or `A..Z`. The whole Latin alphabet is used to represent a number. A funny, but useful case for `36` is when we need to turn a long numeric identifier into something shorter, for example, to make a short url. Can simply represent it in the numeral system with base `36`:
+
+ ```js run
+ alert( 123456..toString(36) ); // 2n9c
+ ```
+
+```warn header="Two dots to call a method"
+Please note that two dots in `123456..toString(36)` is not a typo. If we want to call a method directly on a number, like `toString` in the example above, then we need to place two dots `..` after it.
+
+If we placed a single dot: `123456.toString(36)`, then there would be an error, because JavaScript syntax implies the decimal part after the first dot. And if we place one more dot, then JavaScript knows that the decimal part is empty and now uses the method.
+
+Also could write `(123456).toString(36)`.
+
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
## Rounding
@@ -119,19 +179,31 @@ There are several built-in functions for rounding:
: Rounds up: `3.1` becomes `4`, and `-1.1` becomes `-1`.
`Math.round`
-: Rounds to the nearest integer: `3.1` becomes `3`, `3.6` becomes `4`, the middle case: `3.5` rounds up to `4` too.
+: Rounds to the nearest integer: `3.1` becomes `3`, `3.6` becomes `4`. In the middle cases `3.5` rounds up to `4`, and `-3.5` rounds up to `-3`.
`Math.trunc` (not supported by Internet Explorer)
: Removes anything after the decimal point without rounding: `3.1` becomes `3`, `-1.1` becomes `-1`.
Here's the table to summarize the differences between them:
+<<<<<<< HEAD
| | `Math.floor` | `Math.ceil` | `Math.round` | `Math.trunc` |
| ------ | ------------ | ----------- | ------------ | ------------ |
| `3.1` | `3` | `4` | `3` | `3` |
| `3.6` | `3` | `4` | `4` | `3` |
| `-1.1` | `-2` | `-1` | `-1` | `-1` |
| `-1.6` | `-2` | `-1` | `-2` | `-1` |
+=======
+| | `Math.floor` | `Math.ceil` | `Math.round` | `Math.trunc` |
+|---|---------|--------|---------|---------|
+|`3.1`| `3` | `4` | `3` | `3` |
+|`3.5`| `3` | `4` | `4` | `3` |
+|`3.6`| `3` | `4` | `4` | `3` |
+|`-1.1`| `-2` | `-1` | `-1` | `-1` |
+|`-1.5`| `-2` | `-1` | `-1` | `-1` |
+|`-1.6`| `-2` | `-1` | `-2` | `-1` |
+
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
These functions cover all of the possible ways to deal with the decimal part of a number. But what if we'd like to round the number to `n-th` digit after the decimal?
@@ -141,10 +213,16 @@ For instance, we have `1.2345` and want to round it to 2 digits, getting only `1
ÙÙ
ÙÙ ÙØªØ§Ø¨ØªÙا Ø¨ÙØ°Ù Ø§ÙØ·Ø±ÙÙØ© Ø£ÙØ¶Ùا `â(123456).toString(36)â`.
+<<<<<<< HEAD
````
## Ø§ÙØªÙØ±ÙØ¨ (Rounding)
Ø£ØØ¯ Ø§ÙØ®ØµØ§Ø¦Øµ Ø§ÙØ£Ùثر استخداÙ
ÙØ§ Ø¹ÙØ¯ Ø§ÙØªØ¹Ø§Ù
Ù Ù
ع Ø§ÙØ£Ø¹Ø¯Ø§Ø¯ ÙÙ Ø§ÙØªÙØ±ÙØ¨. ÙÙØ¬Ø¯ Ø§ÙØ¹Ø¯Ùد Ù
Ù Ø§ÙØ¯Ùا٠اÙÙ
دÙ
جة ÙÙØªÙØ±ÙØ¨:
+=======
+ For example, to round the number to the 2nd digit after the decimal, we can multiply the number by `100`, call the rounding function and then divide it back.
+ ```js run
+ let num = 1.23456;
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
alert( Math.round(num * 100) / 100 ); // 1.23456 -> 123.456 -> 123 -> 1.23
```
@@ -162,16 +240,126 @@ For instance, we have `1.2345` and want to round it to 2 digits, getting only `1
Ù
Ø«ÙÙØ§Ø ÙØ¯ÙÙØ§ Ø§ÙØ¹Ø¯Ø¯ `1.2345` ÙÙØ±Ùد ØªÙØ±Ùب Ø¥ÙÙ Ø®Ø§ÙØªÙÙ ÙÙØØµÙ Ø¹ÙÙ `1.23` ÙÙØ·. ÙÙØ¬Ø¯ طرÙÙØªÙÙ ÙÙÙÙØ§Ù
بذÙÙ:
+<<<<<<< HEAD
1- Ø§ÙØ¶Ø±Ø¨ ÙØ§ÙÙØ³Ù
Ø©:
+=======
+ Please note that the result of `toFixed` is a string. If the decimal part is shorter than required, zeroes are appended to the end:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù
Ø«ÙÙØ§Ø ÙØªÙØ±ÙØ¨ Ø§ÙØ±ÙÙ
Ø¥ÙÙ Ø§ÙØ®Ø§ÙØ© Ø§ÙØ«Ø§ÙÙØ© بعد اÙÙØ§ØµÙØ© Ø§ÙØ¹Ø´Ø±ÙØ©Ø ÙÙ
ÙÙÙØ§ ضرب Ø§ÙØ¹Ø¯Ø¯ ÙÙ `100`Ø Ø«Ù
ÙØ³ØªØ¯Ø¹Ù تابع Ø§ÙØªÙØ±ÙØ¨ Ø«Ù
ÙÙØ³Ù
عÙÙ ÙÙØ³ Ø§ÙØ¹Ø¯Ø¯.
+<<<<<<< HEAD
+=======
+ We can convert it to a number using the unary plus or a `Number()` call, e.g. write `+num.toFixed(5)`.
+
+## Imprecise calculations
+
+Internally, a number is represented in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754), so there are exactly 64 bits to store a number: 52 of them are used to store the digits, 11 of them store the position of the decimal point, and 1 bit is for the sign.
+
+If a number is really huge, it may overflow the 64-bit storage and become a special numeric value `Infinity`:
+
+```js run
+alert( 1e500 ); // Infinity
+```
+
+What may be a little less obvious, but happens quite often, is the loss of precision.
+
+Consider this (falsy!) equality test:
+
+```js run
+alert( 0.1 + 0.2 == 0.3 ); // *!*false*/!*
+```
+
+That's right, if we check whether the sum of `0.1` and `0.2` is `0.3`, we get `false`.
+
+Strange! What is it then if not `0.3`?
+
+```js run
+alert( 0.1 + 0.2 ); // 0.30000000000000004
+```
+
+Ouch! Imagine you're making an e-shopping site and the visitor puts `$0.10` and `$0.20` goods into their cart. The order total will be `$0.30000000000000004`. That would surprise anyone.
+
+But why does this happen?
+
+A number is stored in memory in its binary form, a sequence of bits - ones and zeroes. But fractions like `0.1`, `0.2` that look simple in the decimal numeric system are actually unending fractions in their binary form.
+
+```js run
+alert(0.1.toString(2)); // 0.0001100110011001100110011001100110011001100110011001101
+alert(0.2.toString(2)); // 0.001100110011001100110011001100110011001100110011001101
+alert((0.1 + 0.2).toString(2)); // 0.0100110011001100110011001100110011001100110011001101
+```
+
+What is `0.1`? It is one divided by ten `1/10`, one-tenth. In the decimal numeral system, such numbers are easily representable. Compare it to one-third: `1/3`. It becomes an endless fraction `0.33333(3)`.
+
+So, division by powers `10` is guaranteed to work well in the decimal system, but division by `3` is not. For the same reason, in the binary numeral system, the division by powers of `2` is guaranteed to work, but `1/10` becomes an endless binary fraction.
+
+There's just no way to store *exactly 0.1* or *exactly 0.2* using the binary system, just like there is no way to store one-third as a decimal fraction.
+
+The numeric format IEEE-754 solves this by rounding to the nearest possible number. These rounding rules normally don't allow us to see that "tiny precision loss", but it exists.
+
+We can see this in action:
+```js run
+alert( 0.1.toFixed(20) ); // 0.10000000000000000555
+```
+
+And when we sum two numbers, their "precision losses" add up.
+
+That's why `0.1 + 0.2` is not exactly `0.3`.
+
+```smart header="Not only JavaScript"
+The same issue exists in many other programming languages.
+
+PHP, Java, C, Perl, and Ruby give exactly the same result, because they are based on the same numeric format.
+```
+
+Can we work around the problem? Sure, the most reliable method is to round the result with the help of a method [toFixed(n)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed):
+
+```js run
+let sum = 0.1 + 0.2;
+alert( sum.toFixed(2) ); // "0.30"
+```
+
+Please note that `toFixed` always returns a string. It ensures that it has 2 digits after the decimal point. That's actually convenient if we have an e-shopping and need to show `$0.30`. For other cases, we can use the unary plus to coerce it into a number:
+
+```js run
+let sum = 0.1 + 0.2;
+alert( +sum.toFixed(2) ); // 0.3
+```
+
+We also can temporarily multiply the numbers by 100 (or a bigger number) to turn them into integers, do the maths, and then divide back. Then, as we're doing maths with integers, the error somewhat decreases, but we still get it on division:
+
+```js run
+alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3
+alert( (0.28 * 100 + 0.14 * 100) / 100); // 0.4200000000000001
+```
+
+So, the multiply/divide approach reduces the error, but doesn't remove it totally.
+
+Sometimes we could try to evade fractions at all. Like if we're dealing with a shop, then we can store prices in cents instead of dollars. But what if we apply a discount of 30%? In practice, totally evading fractions is rarely possible. Just round them to cut "tails" when needed.
+
+````smart header="The funny thing"
+Try running this:
+
+```js run
+// Hello! I'm a self-increasing number!
+alert( 9999999999999999 ); // shows 10000000000000000
+```
+
+This suffers from the same issue: a loss of precision. There are 64 bits for the number, 52 of them can be used to store digits, but that's not enough. So the least significant digits disappear.
+
+JavaScript doesn't trigger an error in such events. It does its best to fit the number into the desired format, but unfortunately, this format is not big enough.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
````
let num = 1.23456;
alert( Math.floor(num \* 100) / 100 ); // 1.23456 -> 123.456 -> 123 -> 1.23
+<<<<<<< HEAD
+=======
+In most cases, the distinction is unnoticeable, because operators are suited to treat them as the same.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
2- ÙÙØ±Ø¨ Ø§ÙØªØ§Ø¨Ø¹ [`toFixed(n)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) Ø§ÙØ¹Ø¯Ø¯ اÙÙ
ستدع٠Ù
ع٠إÙÙ Ø§ÙØ®Ø§ÙØ© `n` بعد اÙÙØ§ØµÙØ© Ø§ÙØ¹Ø´Ø±ÙØ© ÙÙÙØ±Ø¬Ùع تÙ
Ø«ÙÙÙØ§ ÙØµÙÙØ§ ÙÙÙØªÙجة.
@@ -190,7 +378,11 @@ alert( num.toFixed(1) ); // "12.3"
let num = 12.36;
alert( num.toFixed(1) ); // "12.4"
+<<<<<<< HEAD
```
+=======
+ But do we need this function? Can't we just use the comparison `=== NaN`? Unfortunately not. The value `NaN` is unique in that it does not equal anything, including itself:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ§ØØ¸ Ø£Ù Ù
خرجات Ø§ÙØªØ§Ø¨Ø¹ `toFixed` ÙÙ ÙØµ. Ø¥Ù ÙØ§Ù Ø§ÙØ¬Ø²Ø¡ Ø§ÙØ¹Ø´Ø±Ù Ø£ÙÙ Ù
٠اÙÙ
Ø·ÙÙØ¨Ø ØªÙØ¶Ø§Ù Ø§ÙØ£ØµÙار Ø¥ÙÙ ÙÙØ§ÙØ© Ø§ÙØ±ÙÙ
:
@@ -342,6 +534,7 @@ let num = +prompt("Enter a number", '');
alert( isFinite(num) );
```
+<<<<<<< HEAD
ÙØ±Ø¬Ù Ù
ÙØ§ØØ¸Ø© أ٠اÙÙØ±Ø§Øº أ٠اÙÙ
Ø³Ø§ÙØ© اÙÙØ§ØØ¯Ø© ØªÙØ¹Ø§Ù
Ù Ù
عاÙ
ÙØ© Ø§ÙØµÙر `0` Ù٠جÙ
ÙØ¹ Ø§ÙØªÙابع Ø§ÙØ¹Ø¯Ø¯ÙØ© بÙ
ا ÙÙÙØ§ `isFinite`.
```smart header="اÙÙ
ÙØ§Ø±ÙØ© باستخداÙ
`Object.is`"
@@ -350,10 +543,53 @@ alert( isFinite(num) );
1. Ø£ÙÙ ÙØ¹Ù
Ù Ù
ع `NaN`: Ø£Ù `Object.is(NaN, NaN) === true` ÙÙØ°Ø§ Ø£Ù
ر Ø¬ÙØ¯.
2. اÙÙÙÙ
تا٠`0` Ù `-0` Ù
ختÙÙØªØ§Ù: `Object.is(0, -0) === false`Ø Ø§ÙØ£Ù
ر صØÙØ ØªÙÙÙÙØ§Ø ÙØ£Ù Ø§ÙØ¹Ø¯Ø¯ ÙØ¯Ù٠إشارة داخÙÙÙØ§ Ù
Ù
ا ÙØ¬Ø¹Ù اÙÙÙÙ
Ù
ختÙÙØ© ØØªÙ ÙÙ ÙØ§Ùت باÙÙ Ø§ÙØ®Ø§Ùات Ø£ØµÙØ§Ø±Ùا.
+=======
+Please note that an empty or a space-only string is treated as `0` in all numeric functions including `isFinite`.
+
+````smart header="`Number.isNaN` and `Number.isFinite`"
+[Number.isNaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) and [Number.isFinite](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite) methods are the more "strict" versions of `isNaN` and `isFinite` functions. They do not autoconvert their argument into a number, but check if it belongs to the `number` type instead.
+
+- `Number.isNaN(value)` returns `true` if the argument belongs to the `number` type and it is `NaN`. In any other case, it returns `false`.
+
+ ```js run
+ alert( Number.isNaN(NaN) ); // true
+ alert( Number.isNaN("str" / 2) ); // true
+
+ // Note the difference:
+ alert( Number.isNaN("str") ); // false, because "str" belongs to the string type, not the number type
+ alert( isNaN("str") ); // true, because isNaN converts string "str" into a number and gets NaN as a result of this conversion
+ ```
+
+- `Number.isFinite(value)` returns `true` if the argument belongs to the `number` type and it is not `NaN/Infinity/-Infinity`. In any other case, it returns `false`.
+
+ ```js run
+ alert( Number.isFinite(123) ); // true
+ alert( Number.isFinite(Infinity) ); // false
+ alert( Number.isFinite(2 / 0) ); // false
+
+ // Note the difference:
+ alert( Number.isFinite("123") ); // false, because "123" belongs to the string type, not the number type
+ alert( isFinite("123") ); // true, because isFinite converts string "123" into a number 123
+ ```
+
+In a way, `Number.isNaN` and `Number.isFinite` are simpler and more straightforward than `isNaN` and `isFinite` functions. In practice though, `isNaN` and `isFinite` are mostly used, as they're shorter to write.
+````
+
+```smart header="Comparison with `Object.is`"
+There is a special built-in method `Object.is` that compares values like `===`, but is more reliable for two edge cases:
+
+1. It works with `NaN`: `Object.is(NaN, NaN) === true`, that's a good thing.
+2. Values `0` and `-0` are different: `Object.is(0, -0) === false`, technically that's correct because internally the number has a sign bit that may be different even if all other bits are zeroes.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙÙÙ Ø§ÙØªØ§Ø¨Ø¹ `Object.is(a, b)â` ÙÙØ³ `a === b` Ù٠باÙÙ Ø§ÙØØ§ÙØ§Øª.
+<<<<<<< HEAD
ØªÙØ³ØªØ®Ø¯Ù
طرÙÙØ© اÙÙ
ÙØ§Ø²ÙØ© ÙØ°Ù ØºØ§ÙØ¨Ùا ÙÙ ØªÙØµÙÙ JavaScript. Ø¹ÙØ¯Ù
ا ØªØØªØ§Ø¬ Ø®ÙØ§Ø±Ø²Ù
ÙØ© ÙÙ
ÙØ§Ø²ÙØ© ÙÙÙ ÙÙÙ
تÙÙ Ù
ØªØ·Ø§Ø¨ÙØªØ§Ù تÙ
اÙ
ÙØ§ ÙØ¥ÙÙØ§ تستخدÙ
`Object.is` (ØªÙØ³ÙÙ
ÙÙ٠داخÙÙÙØ§ اÙÙÙÙ
Ø© Ø°Ø§ØªÙØ§ "[SameValue](https://tc39.github.io/ecma262/#sec-samevalue)").
+=======
+We mention `Object.is` here, because it's often used in JavaScript specification. When an internal algorithm needs to compare two values for being exactly the same, it uses `Object.is` (internally called [SameValue](https://tc39.github.io/ecma262/#sec-samevalue)).
+```
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## parseInt Ù parseFloat
@@ -365,7 +601,15 @@ alert(+'100px'); // NaN
Ø§ÙØ§Ø³ØªØ«Ùاء اÙÙØÙØ¯ Ù٠اÙÙ
Ø³Ø§ÙØ§Øª اÙÙØ§Ø±ØºØ© Ø¨Ø¨Ø¯Ø§ÙØ© Ø£Ù ÙÙØ§ÙØ© اÙÙØµØ إذ ÙØªÙ
تجاÙÙÙØ§.
+<<<<<<< HEAD
ÙÙÙØ ÙÙØ¬Ø¯ ÙØ¯ÙÙØ§ Ù٠اÙÙØ§Ùع ÙÙÙ
ÙØ§ باÙÙØØ¯Ø§ØªØ Ù
ث٠`"100px"` Ø£Ù `"12pt"` ÙÙ CSS. ÙÙ Ø§ÙØ¹Ø¯Ùد Ù
Ù Ø§ÙØ¯ÙÙ Ø£ÙØ¶Ø§Ø ÙÙÙØÙ٠رÙ
ز Ø§ÙØ¹Ù
ÙØ© باÙÙÙÙ
Ø©Ø ÙÙ
Ø«ÙÙØ§Ø ÙØ¯ÙÙØ§ `"19â¬"` ÙÙØ±Ùد استخراج ÙÙÙ
Ø© Ø¹Ø¯Ø¯ÙØ© Ù
٠ذÙÙ. ÙØ°Ø§ Ù
ا ÙÙÙÙ
Ø¨Ù Ø§ÙØªØ§Ø¨Ø¹Ø§Ù `parseInt` Ù `parseFloat`Ø Ø¥Ø° ÙÙØ±Ø¢Ù Ø§ÙØ¹Ø¯Ø¯ Ù
٠اÙÙØµ اÙÙ
Ø¹Ø·Ù ØØªÙ تعجزا٠عÙ٠ذÙÙ ÙØªØªÙÙÙ Ø§ÙØ¹Ù
ÙÙØ©. ÙÙ ØØ§Ù ÙØ¬Ùد Ø®Ø·Ø£Ø ÙØ¹ÙØ¯Ø§Ù Ø§ÙØ¹Ø¯Ø¯ اÙÙ
ÙØ¬ÙÙ
ÙÙØ¹. ÙÙØ¹Ùد Ø§ÙØªØ§Ø¨Ø¹ `parseInt` Ø¹Ø¯Ø¯ÙØ§ صØÙØÙØ§Ø Ø¨ÙÙÙ
ا ÙØ¹Ùد Ø§ÙØªØ§Ø¨Ø¹`parseFloat` Ø¹Ø¯Ø¯ÙØ§ عشرÙÙØ§:
+=======
+But in real life, we often have values in units, like `"100px"` or `"12pt"` in CSS. Also in many countries, the currency symbol goes after the amount, so we have `"19â¬"` and would like to extract a numeric value out of that.
+
+That's what `parseInt` and `parseFloat` are for.
+
+They "read" a number from a string until they can't. In case of an error, the gathered number is returned. The function `parseInt` returns an integer, whilst `parseFloat` will return a floating-point number:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
alert(parseInt('100px')); // 100
@@ -404,8 +648,13 @@ alert(parseInt('2n9c', 36)); // 123456
alert( Math.random() ); // ... (أ٠رÙÙ
Ø¹Ø´ÙØ§Ø¦Ù)
```
+<<<<<<< HEAD
`Math.max(a, b, c...)` / `Math.min(a, b, c...)`
: ØªÙØ±Ø¬Ùع اÙÙÙÙ
Ø© Ø§ÙØ£Ùبر Ø£Ù Ø§ÙØ£ØµØºØ± Ù
٠اÙÙ
ÙØ¹Ø§Ù
ÙÙØ§Øª
+=======
+`Math.max(a, b, c...)` and `Math.min(a, b, c...)`
+: Returns the greatest and smallest from the arbitrary number of arguments.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
alert( Math.max(3, 5, -10, 0, 1) ); // 5
@@ -434,7 +683,18 @@ For different numeral systems:
- `parseInt(str, base)` parses the string `str` into an integer in numeral system with given `base`, `2 ⤠base ⤠36`.
- `num.toString(base)` converts a number to a string in the numeral system with the given `base`.
+<<<<<<< HEAD
## اÙÙ
ÙØ®Øµ
+=======
+For regular number tests:
+
+- `isNaN(value)` converts its argument to a number and then tests it for being `NaN`
+- `Number.isNaN(value)` checks whether its argument belongs to the `number` type, and if so, tests it for being `NaN`
+- `isFinite(value)` converts its argument to a number and then tests it for not being `NaN/Infinity/-Infinity`
+- `Number.isFinite(value)` checks whether its argument belongs to the `number` type, and if so, tests it for not being `NaN/Infinity/-Infinity`
+
+For converting values like `12pt` and `100px` to a number:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØªØ§Ø¨Ø© أعداد ÙØ¨Ùرة:
- أضÙÙ `"e"` Ù
ع عدد Ø§ÙØ£ØµÙار Ø§ÙØ®Ø§ØµØ© Ø¨Ø§ÙØ¹Ø¯Ø¯ اÙÙ
Ø·ÙÙØ¨Ø Ù
Ø«Ù: `123e6` ÙÙ `123` Ù
ع 6 Ø£ØµÙØ§Ø±.
@@ -452,6 +712,10 @@ For different numeral systems:
- Ø§ÙØªÙØ±ÙØ¨ باستخداÙ
`Math.floor`Ø Ø£Ù `Math.ceil`Ø Ø£Ù `Math.trunc`Ø Ø£Ù `Math.round` Ø£Ù `num.toFixed(precision)â`.
- ØªØ°ÙØ± ÙØ¬Ùد Ø¶ÙØ§Ø¹ ÙÙ Ø¯ÙØ© Ø§ÙØ¬Ø²Ø¡ Ø§ÙØ¹Ø´Ø±Ù Ø¹ÙØ¯ Ø§ÙØªØ¹Ø§Ù
Ù Ù
ع اÙÙØ³Ùر.
+<<<<<<< HEAD
ÙÙÙ
Ø²ÙØ¯ Ù
Ù Ø§ÙØ¯ÙØ§Ù Ø§ÙØ±ÙØ§Ø¶ÙØ©:
- Ø§Ø·ÙØ¹ عÙ٠اÙÙØ§Ø¦Ù [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) Ø¹ÙØ¯Ù
ا ØªØØªØ§Ø¬ ذÙÙØ ÙØ°Ù اÙÙ
ÙØªØ¨Ø© ØµØºÙØ±Ø© Ø¬Ø¯ÙØ§Ø ÙÙÙÙØ§ ØªØºØ·Ù Ø§ÙØ§ØØªÙاجات Ø§ÙØ£Ø³Ø§Ø³ÙØ©.
````
+=======
+- See the [Math](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Math) object when you need them. The library is very small but can cover basic needs.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/05-data-types/03-string/1-ucfirst/solution.md b/1-js/05-data-types/03-string/1-ucfirst/solution.md
index 14ca02972..d60d92dd9 100644
--- a/1-js/05-data-types/03-string/1-ucfirst/solution.md
+++ b/1-js/05-data-types/03-string/1-ucfirst/solution.md
@@ -6,12 +6,16 @@ let newStr = str[0].toUpperCase() + str.slice(1);
ÙÙÙØ ÙÙØ¬Ø¯ Ù
Ø´ÙÙØ© ØµØºÙØ±Ø©Ø ÙÙÙ Ø¥Ù ÙØ§Ù `str` ÙØ§Ø±ØºÙØ§Ø ÙØ³ÙØµØ¨Ø `str[0]â` ÙÙÙ
Ø© ØºÙØ± Ù
Ø¹Ø±ÙØ© `undefined`Ø ÙÙØ£Ù `undefined` ÙØ§ ÙÙ
ÙÙ Ø§ÙØ¯Ø§ÙØ© `toUpperCase()â` ÙØ³ÙØ¸ÙØ± خطأ.
+<<<<<<< HEAD
ÙÙØ¬Ø¯ طرÙÙØªÙ٠بدÙÙØªÙÙ ÙÙØ§:
1- استخداÙ
`str.charAt(0)â`Ø ÙØ£ÙÙØ§ ØªÙØ±Ø¬Ùع ÙØµÙا دائÙ
ÙØ§ (ربÙ
ا ÙØµÙا ÙØ§Ø±ØºÙا).
2- Ø¥Ø¶Ø§ÙØ© اختبار ÙÙ ØØ§Ù ÙØ§Ù اÙÙØµ ÙØ§Ø±ØºÙا.
ÙÙØ§ Ø§ÙØ®Ùار Ø§ÙØ«Ø§ÙÙ:
+=======
+The easiest way out is to add a test for an empty string, like this:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run demo
function ucFirst(str) {
@@ -22,4 +26,3 @@ function ucFirst(str) {
alert( ucFirst("john") ); // John
```
-
diff --git a/1-js/05-data-types/03-string/3-truncate/task.md b/1-js/05-data-types/03-string/3-truncate/task.md
index afa101781..455238abd 100644
--- a/1-js/05-data-types/03-string/3-truncate/task.md
+++ b/1-js/05-data-types/03-string/3-truncate/task.md
@@ -7,7 +7,7 @@ importance: 5
Ø§ÙØ´Ø¦ Ø¯Ø§ÙØ© باسÙ
`truncate(str, maxlength)â` ØªÙØØµ Ø·Ù٠اÙÙØµ `str` ÙØªØ³ØªØ¨Ø¯Ù ÙÙØ§ÙØªÙ Ø§ÙØªÙ ØªØªØ¬Ø§ÙØ² Ø§ÙØØ¯ `maxlength` Ø¨Ø§ÙØ±Ù
ز `"â¦"` ÙØ¬Ø¹Ù Ø·ÙÙÙØ§ ÙØ³Ø§ÙÙ `maxlength` Ø¨Ø§ÙØ¶Ø¨Ø·. ÙØ¬Ø¨ أ٠تÙÙÙ Ù
خرجات Ø§ÙØ¯Ø§ÙØ© اÙÙØµ اÙÙ
ÙØµÙص (ÙÙ ØØ§Ù ØØ¯Ø« ذÙÙ). Ù
Ø«ÙÙØ§:
```js
-truncate("What I'd like to tell on this topic is:", 20) = "What I'd like to teâ¦"
+truncate("What I'd like to tell on this topic is:", 20) == "What I'd like to teâ¦"
-truncate("Hi everyone!", 20) = "Hi everyone!"
+truncate("Hi everyone!", 20) == "Hi everyone!"
```
diff --git a/1-js/05-data-types/03-string/article.md b/1-js/05-data-types/03-string/article.md
index e83e5aa67..5c044ba06 100644
--- a/1-js/05-data-types/03-string/article.md
+++ b/1-js/05-data-types/03-string/article.md
@@ -47,9 +47,13 @@ let guestList = "Guests: // Error: Unexpected token ILLEGAL
* John";
```
+<<<<<<< HEAD
أت٠استخداÙ
Ø¹ÙØ§Ù
ات Ø§ÙØ§Ùتباس اÙÙØ±Ø¯ÙØ© ÙØ§ÙØ«ÙØ§Ø¦ÙØ© Ù٠أÙÙØ§Øª Ù
Ø¨ÙØ±Ø© Ù
Ù Ø¥ÙØ´Ø§Ø¡ اÙÙØºØ©Ø Ø¹ÙØ¯Ù
ا ÙÙ
ÙÙØ¤Ø®Ùذ Ø¨Ø§ÙØØ³Ø¨Ø§Ù Ø§ÙØØ§Ø¬Ø© Ø¥ÙÙ ÙØµ Ù
تعدد Ø§ÙØ£Ø³Ø·Ø±. Ø¸ÙØ±Øª اÙÙØ§ØµÙØ© Ø§ÙØ¹ÙÙÙØ© اÙÙ
Ø§Ø¦ÙØ© Ù
Ø¤Ø®Ø±ÙØ§ ÙÙØ°Ø§ ÙØ¥ÙÙØ§ Ù
تعددة Ø§ÙØ§Ø³ØªØ¹Ù
Ø§ÙØ§Øª.
+=======
+Single and double quotes come from ancient times of language creation, when the need for multiline strings was not taken into account. Backticks appeared much later and thus are more versatile.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
-Backticks also allow us to specify a "template function" before the first backtick. The syntax is: func`string`. The function `func` is called automatically, receives the string and embedded expressions and can process them. This is called "tagged templates". This feature makes it easier to implement custom templating, but is rarely used in practice. You can read more about it in the [manual](mdn:/JavaScript/Reference/Template_literals#Tagged_templates).
+Backticks also allow us to specify a "template function" before the first backtick. The syntax is: func`string`. The function `func` is called automatically, receives the string and embedded expressions and can process them. This feature is called "tagged templates", it's rarely seen, but you can read about it in the MDN: [Template literals](mdn:/JavaScript/Reference/Template_literals#Tagged_templates).
## Ø§ÙØ±Ù
ÙØ² Ø§ÙØ®Ø§ØµØ©
Ù
ا Ø²Ø§Ù Ø¨Ø§ÙØ¥Ù
ÙØ§Ù ÙØªØ§Ø¨Ø© ÙØµÙص Ù
تعددة Ø§ÙØ£Ø³Ø·Ø± باستخداÙ
Ø¹ÙØ§Ù
ات Ø§ÙØ§Ùتباس Ø§ÙØ£ØØ§Ø¯ÙØ© ÙØ§ÙØ«ÙØ§Ø¦ÙØ© باستخداÙ
Ù
ا ÙØ³Ù
٠ب "رÙ
ز Ø§ÙØ³Ø·Ø± Ø§ÙØ¬Ø¯Ùد"Ø ÙØ§Ùذ٠ÙÙÙØªÙب `â\n`Ø ÙÙØ±Ù
ز ÙØ³Ø·Ø± Ø¬Ø¯ÙØ¯:
@@ -58,10 +62,17 @@ Backticks also allow us to specify a "template function" before the first backti
```js run
let guestList = "Guests:\n * John\n * Pete\n * Mary";
+<<<<<<< HEAD
alert(guestList); // ÙØ§Ø¦Ù
Ø© Ù
تعددة Ø§ÙØ£Ø³Ø·Ø± Ø¨Ø§ÙØ¶ÙÙÙ
```
Ù
Ø«ÙÙØ§Ø Ø§ÙØ³Ø·Ø±ÙÙ Ø§ÙØªØ§ÙÙÙÙ Ù
تÙ
Ø§Ø«ÙØ§ÙØ ÙÙÙÙÙ
ا Ù
ÙØªÙبÙ٠بطرÙÙØ© Ù
ختÙÙØ©:
+=======
+alert(guestList); // a multiline list of guests, same as above
+```
+
+As a simpler example, these two lines are equal, just written differently:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let str1 = "Hello\nWorld"; // سطرا٠باستخداÙ
"رÙ
ز Ø§ÙØ³Ø·Ø± Ø§ÙØ¬Ø¯Ùد"
@@ -73,6 +84,7 @@ World`;
alert(str1 == str2); // true
```
+<<<<<<< HEAD
ÙÙØ¬Ø¯ رÙ
ÙØ² خاصة أخر٠أÙÙ Ø§ÙØªØ´Ø§Ø±Ùا.
ÙØ°Ù اÙÙØ§Ø¦Ù
Ø© ÙØ§Ù
ÙØ©:
@@ -88,32 +100,36 @@ alert(str1 == str2); // true
| `â\xXX` | ØµÙØºØ© رÙ
ز ÙÙÙÙÙÙØ¯ Ù
ع عدد ست عشر٠Ù
ÙØ¹Ø·Ù `XX`Ø Ù
ثاÙ: `'â \x7A'` ÙÙ ÙÙØ³Ùا `'z'`. |
| `â\uXXXX` | ØµÙØºØ© رÙ
ز ÙÙÙÙÙÙØ¯ Ù
ع عدد ست Ø¹Ø´Ø±ÙØ© `XXXX` Ù٠تشÙÙØ± UTF-16Ø Ù
Ø«ÙÙØ§Ø `â\u00A9` â Ù٠اÙÙÙÙÙÙÙØ¯ ÙØ±Ù
ز ØÙÙ٠اÙÙØ³Ø® `©`. ÙØ¬Ø¨ Ø£Ù ÙÙÙÙ Ù
ÙÙÙ Ù
Ù 6 Ø®Ø§ÙØ§Øª ست Ø¹Ø´Ø±ÙØ©. |
| â`\u{Xâ¦XXXXXX}â` | (1 Ø¥ÙÙ 6 Ø£ØØ±Ù ست Ø¹Ø´Ø±ÙØ©) رÙ
ز ÙÙÙÙÙÙØ¯ Ù
ع تشÙÙØ± UTF-32 اÙÙ
عطÙ. ØªÙØ´ÙÙÙÙØ± بعض Ø§ÙØ±Ù
ÙØ² Ø§ÙØ®Ø§ØµØ© برÙ
ز٠ÙÙÙÙÙÙØ¯Ø ÙØªØ£Ø®Ø° 4 Ø¨Ø§ÙØª. ÙÙØ°Ø§ ÙÙ
ÙÙÙØ§ إدخا٠شÙÙØ±Ø§Øª Ø·ÙÙÙØ©. |
+=======
+There are other, less common special characters:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
| Character | Description |
|-----------|-------------|
|`\n`|New line|
-|`\r`|Carriage return: not used alone. Windows text files use a combination of two characters `\r\n` to represent a line break. |
-|`\'`, `\"`|Quotes|
+|`\r`|In Windows text files a combination of two characters `\r\n` represents a new break, while on non-Windows OS it's just `\n`. That's for historical reasons, most Windows software also understands `\n`. |
+|`\'`, `\"`, \\`|Quotes|
|`\\`|Backslash|
|`\t`|Tab|
-|`\b`, `\f`, `\v`| Backspace, Form Feed, Vertical Tab -- kept for compatibility, not used nowadays. |
-|`\xXX`|Unicode character with the given hexadecimal Unicode `XX`, e.g. `'\x7A'` is the same as `'z'`.|
-|`\uXXXX`|A Unicode symbol with the hex code `XXXX` in UTF-16 encoding, for instance `\u00A9` -- is a Unicode for the copyright symbol `©`. It must be exactly 4 hex digits. |
-|`\u{Xâ¦XXXXXX}` (1 to 6 hex characters)|A Unicode symbol with the given UTF-32 encoding. Some rare characters are encoded with two Unicode symbols, taking 4 bytes. This way we can insert long codes. |
+|`\b`, `\f`, `\v`| Backspace, Form Feed, Vertical Tab -- mentioned for completeness, coming from old times, not used nowadays (you can forget them right now). |
+
+As you can see, all special characters start with a backslash character `\`. It is also called an "escape character".
-Examples with Unicode:
+Because it's so special, if we need to show an actual backslash `\` within the string, we need to double it:
```js run
-alert( "\u00A9" ); // ©
-alert( "\u{20331}" ); // 佫, a rare Chinese hieroglyph (long Unicode)
-alert( "\u{1F60D}" ); // ð, a smiling face symbol (another long Unicode)
+alert( `The backslash: \\` ); // The backslash: \
```
+<<<<<<< HEAD
// (رÙ
ز ÙØ§Ø¯Ø± Ù
٠اÙÙÙØ±ÙغÙÙÙÙØ© Ø§ÙØµÙÙÙØ© (ÙÙÙÙÙÙØ¯ Ø·ÙÙÙ
alert( "\u{20331}" ); // 佫
// (رÙ
ز ÙØ¬Ù Ù
بتسÙ
(ÙÙÙÙÙÙØ¯ Ø·ÙÙ٠آخر
alert( "\u{1F60D}" ); // ð
+=======
+So-called "escaped" quotes `\'`, `\"`, \\` are used to insert a quote into the same-quoted string.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
@@ -128,14 +144,18 @@ alert( 'I*!*\'*/!*m the Walrus!' ); // *!*I'm*/!* the Walrus!
Of course, only the quotes that are the same as the enclosing ones need to be escaped. So, as a more elegant solution, we could switch to double quotes or backticks instead:
```js run
-alert( `I'm the Walrus!` ); // I'm the Walrus!
+alert( "I'm the Walrus!" ); // I'm the Walrus!
```
+<<<<<<< HEAD
ÙÙÙ Ù
اذا Ø¥Ù Ø£Ø±Ø¯ÙØ§ عرض شرطة Ù
Ø§Ø¦ÙØ© Ø®ÙÙÙØ© ضÙ
٠اÙÙØµØ ÙÙ
Ù٠ذÙÙØ ÙÙÙÙØ§ ÙØØªØ§Ø¬ Ø¥ÙÙ ØªÙØ±Ø§Ø±Ùا ÙÙØ°Ø§ `\\`:
```js run
alert( `The backslash: \\` ); // The backslash: \
```
+=======
+Besides these special characters, there's also a special notation for Unicode codes `\uâ¦`, it's rarely used and is covered in the optional chapter about [Unicode](info:unicode).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## Ø·Ù٠اÙÙØµ
تØÙ
Ù Ø§ÙØ®Ø§ØµÙØ© `length` Ø·Ù٠اÙÙØµ:
@@ -147,32 +167,57 @@ alert( `My\n`.length ); // 3
ÙØ§ØØ¸ Ø£Ù `n\` Ù٠رÙ
ز Ø®Ø§ØµØ ÙØ°Ø§ ÙÙÙÙ Ø·ÙÙ Ø§ÙØ³ÙØ³ÙØ© اÙÙØ¹ÙÙ ÙÙ `3`.
+<<<<<<< HEAD
```warn header="**`length` ÙÙ Ø®Ø§ØµÙØ©**"
ÙÙØ®Ø·Ùئ بعض Ø§ÙØ£Ø´Ø®Ø§Øµ ذÙÙ Ø§ÙØ®ÙÙÙØ§Øª Ø¨ÙØºØ§Øª برÙ
Ø¬ÙØ© Ø£Ø®Ø±Ù Ù ÙØ³ØªØ¯Ø¹ÙÙ `str.length()â ` بدÙÙØ§ Ù
٠استدعاء `str.length` ÙÙØ·. ÙØ°Ø§ ÙØ§ ÙØ¹Ù
Ù ÙØ°Ø§ Ø§ÙØªØ§Ø¨Ø¹ ÙØ¹Ø¯Ù
ÙØ¬ÙدÙ. ÙÙØ§ØØ¸ Ø£Ù `str.length` ÙÙ Ø®Ø§ØµÙØ© Ø¹Ø¯Ø¯ÙØ©Ø ÙÙÙØ³ ØªØ§Ø¨Ø¹ÙØ§ ÙÙØ§ ØØ§Ø¬Ø© ÙÙØ¶Ø¹ ÙÙØ³ÙÙ Ø¨Ø¹Ø¯ÙØ§.
+=======
+```warn header="`length` is a property"
+People with a background in some other languages sometimes mistype by calling `str.length()` instead of just `str.length`. That doesn't work.
+
+Please note that `str.length` is a numeric property, not a function. There is no need to add parenthesis after it. Not `.length()`, but `.length`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
## اÙÙØµÙ٠إÙÙ Ù
ØØ§Ø±Ù Ø³ÙØ³ÙØ©
+<<<<<<< HEAD
ÙÙØØµÙ٠عÙÙ ØØ±Ù ÙÙ Ù
ÙØ§Ù Ù
عÙÙ Ù
Ù Ø§ÙØ³ÙØ³ÙØ© اÙÙØµÙØ© `pos`Ø Ø§Ø³ØªØ®Ø¯Ù
Ø§ÙØ£ÙÙØ§Ø³ اÙÙ
عÙÙÙØ© `[pos]` Ø£Ù Ø§Ø³ØªØ¯Ø¹Ù Ø§ÙØªØ§Ø¨Ø¹ [str.charAt(pos)](mdn:js/String/charAt). ÙØ¨Ø¯Ø£ Ø£ÙÙ ØØ±Ù Ù٠اÙÙ
ÙØ¶Ø¹ رÙÙ
ØµÙØ±:
+=======
+To get a character at position `pos`, use square brackets `[pos]` or call the method [str.at(pos)](mdn:js/String/at). The first character starts from the zero position:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let str = `Hello`;
// the first character
alert( str[0] ); // H
-alert( str.charAt(0) ); // H
+alert( str.at(0) ); // H
// the last character
alert( str[str.length - 1] ); // o
+alert( str.at(-1) );
```
+<<<<<<< HEAD
Ø§ÙØ£ÙÙØ§Ø³ اÙÙ
عÙÙÙØ© Ù٠طرÙÙØ© Ø¬Ø¯ÙØ¯Ø© ÙÙØØµÙ٠عÙÙ ØØ±ÙØ Ø¨ÙÙÙ
ا Ø§ÙØªØ§Ø¨Ø¹ `charAt` Ù
ÙØ¬Ùد ÙØ£Ø³Ø¨Ø§Ø¨ ØªØ§Ø±ÙØ®ÙØ©. Ø§ÙØ§Ø®ØªÙا٠اÙÙØÙØ¯ بÙÙÙÙ
ا Ù٠إ٠ÙÙ
تجد Ø§ÙØ£ÙÙØ§Ø³ اÙÙ
ربعة `[]` Ø§ÙØØ±Ù ØªÙØ±Ø¬Ùع اÙÙÙÙ
Ø© `undefined` بÙÙÙ
ا ÙÙØ±Ø¬Ùع `charAt` ÙØµÙا ÙØ§Ø±ØºÙا:
+=======
+As you can see, the `.at(pos)` method has a benefit of allowing negative position. If `pos` is negative, then it's counted from the end of the string.
+
+So `.at(-1)` means the last character, and `.at(-2)` is the one before it, etc.
+
+The square brackets always return `undefined` for negative indexes, for instance:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let str = `Hello`;
+<<<<<<< HEAD
alert( str[1000] ); // undefined
alert( str.charAt(1000) ); // '' (Ø³ÙØ³ÙØ© ÙØµÙØ© ÙØ§Ø±Øº)
+=======
+alert( str[-2] ); // undefined
+alert( str.at(-2) ); // l
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
ÙÙ
ÙÙÙØ§ Ø£ÙØ¶Ø§ Ø§ÙØªÙÙÙ Ø®ÙØ§Ù جÙ
ÙØ¹ Ù
ØØ§Ø±Ù Ø³ÙØ³ÙØ© باستخداÙ
`for..of`:
@@ -222,7 +267,7 @@ alert( 'Interface'.toLowerCase() ); // interface
Ø£Ù Ø¥Ù Ø£Ø±Ø¯ÙØ§ بتغÙÙØ± ØØ§ÙØ© ØØ±Ù ÙØ§ØØ¯ ÙÙØ·:
-```js
+```js run
alert( 'Interface'[0].toLowerCase() ); // 'i'
```
@@ -312,6 +357,7 @@ if (str.indexOf("Widget") != -1) {
}
```
+<<<<<<< HEAD
#### The bitwise NOT trick
One of the old tricks used here is the [bitwise NOT](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT) `~` operator. It converts the number to a 32-bit integer (removes the decimal part if exists) and then reverses all bits in its binary representation.
@@ -350,6 +396,8 @@ To be precise though, as big numbers are truncated to 32 bits by `~` operator, t
ÙØ§ ÙØ¬Ø¯ ÙØ°Ù Ø§ÙØ®Ø¯Ø¹Ø© ØØ§ÙÙÙØ§ سÙÙ ÙÙ Ø§ÙØ´ÙÙØ±Ø§Øª اÙÙØ¯ÙÙ
Ø©Ø ÙØ°ÙÙ ÙØ£Ù JavaScript ÙÙØ±Øª Ø§ÙØªØ§Ø¨Ø¹ `â.includes` (Ø³ØªØ¬Ø¯ÙØ§ ÙÙ Ø§ÙØ£Ø³ÙÙ).
+=======
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
### includes, startsWith, endsWith
ÙÙØ±Ø¬Ùع Ø§ÙØªØ§Ø¨Ø¹ Ø§ÙØ£ØØ¯Ø« [str.includes(substr, pos)](mdn:js/String/includes) اÙÙÙÙ
Ø© اÙÙ
ÙØ·ÙÙØ© `true` Ø£Ù `false` ÙÙÙÙØ§ ÙÙ
ا Ø¥Ù ÙØ§Ùت Ø§ÙØ³ÙØ³ÙØ© اÙÙØµÙØ© `str` ØªØØªÙ٠عÙÙ Ø§ÙØ³ÙØ³ÙØ© اÙÙØµÙØ© اÙÙØ±Ø¹ÙØ© `substr`. ÙØ°Ù ÙÙ Ø§ÙØ·Ø±ÙÙØ© Ø§ÙØµØÙØØ© ÙÙ ØØ§Ù Ø£Ø±Ø¯ÙØ§ Ø§ÙØªØ£Ùد Ù
Ù ÙØ¬Ùد تطاب٠جزء Ù
Ù Ø³ÙØ³ÙØ© ضÙ
Ù Ø³ÙØ³ÙØ© Ø£Ø®Ø±ÙØ ÙÙØ§ ÙÙÙ
ÙØ§ Ù
ÙØ¶Ø¹Ù:
@@ -370,8 +418,8 @@ alert( "Widget".includes("id", 3) ); // false, from position 3 there is no "id"
ÙØ¹Ù
Ù Ø§ÙØªØ§Ø¨Ø¹Ø§Ù [str.startsWith](mdn:js/String/startsWith) Ù [str.endsWith](mdn:js/String/endsWith) بÙ
ا ÙÙ ÙØ§Ø¶Ø Ù
Ù Ù
سÙ
ÙØ§ØªÙÙ
Ø§Ø "Ø³ÙØ³ÙØ© ÙØµÙØ© تبدأ بÙ"Ø Ù "Ø³ÙØ³ÙØ© ÙØµÙØ© ØªÙØªÙ٠بÙ" عÙÙ Ø§ÙØªÙاÙÙ:
```js run
-alert( "Widget".startsWith("Wid") ); // true, "Widget" starts with "Wid"
-alert( "Widget".endsWith("get") ); // true, "Widget" ends with "get"
+alert( "*!*Wid*/!*get".startsWith("Wid") ); // true, "Widget" starts with "Wid"
+alert( "Wid*!*get*/!*".endsWith("get") ); // true, "Widget" ends with "get"
```
## Ø¬ÙØ¨ جزء Ù
Ù ÙØµ
@@ -405,10 +453,17 @@ There are 3 methods in JavaScript to get a substring: `substring`, `substr` and
alert( str.slice(-4, -1) ); // 'gif'
```
+<<<<<<< HEAD
### **`str.substring(start [, end])â`**
ÙÙØ±Ø¬Ùع ÙØ°Ø§ Ø§ÙØªØ§Ø¨Ø¹ Ø¬Ø²Ø¡ÙØ§ Ù
٠اÙÙØµ اÙÙØ§Ùع بÙ٠اÙÙ
ÙØ¶Ø¹ `start` ÙØ§ÙÙ
ÙØ¶Ø¹ `end`.
`. ÙØ´Ø¨Ù ÙØ°Ø§ Ø§ÙØªØ§Ø¨Ø¹ ØªÙØ±ÙØ¨ÙØ§ Ø§ÙØªØ§Ø¨Ø¹ `slice`Ø ÙÙÙÙ ÙØ³Ù
Ø Ø¨ÙÙ٠اÙÙ
عاÙ
Ù `start` Ø£ÙØ¨Ø± Ù
Ù `end`.
+=======
+`str.substring(start [, end])`
+: Returns the part of the string *between* `start` and `end` (not including `end`).
+
+ This is almost the same as `slice`, but it allows `start` to be greater than `end` (in this case it simply swaps `start` and `end` values).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù
Ø«ÙÙØ§:
@@ -450,6 +505,7 @@ There are 3 methods in JavaScript to get a substring: `substring`, `substr` and
alert( str.substr(-4, 2) ); // ØØ±ÙÙÙ Ø§Ø¨ØªØ¯Ø§Ø¡ÙØ§ Ù
٠اÙÙ
ÙØ¶Ø¹ Ø§ÙØ±Ø§Ø¨Ø¹
```
+<<<<<<< HEAD
ÙÙÙÙÙÙØ®ÙÙØµ ÙØ°Ù Ø§ÙØªÙابع ÙØªØ¬Ùب Ø§ÙØ®ÙØ· بÙÙÙØ§:
| Ø§ÙØªØ§Ø¨Ø¹ | ÙÙØªØ·Ø¹ ... | اÙÙ
ÙØ§Ø¶Ø¹ Ø§ÙØ³Ø§Ùبة |
@@ -457,12 +513,29 @@ There are 3 methods in JavaScript to get a substring: `substring`, `substr` and
| `slice(start, end)â` | Ù
٠اÙÙ
ÙØ¶Ø¹ `start` Ø¥Ù٠اÙÙ
ÙØ¶Ø¹ `end` (بÙ
ا ÙØ§ ÙØªØ¶Ù
Ù `end`) | Ù
سÙ
ÙØØ© ÙÙÙØ§ اÙÙ
عاÙ
ÙÙÙ |
| `substring(start, end)â` | Ù
ا بÙ٠اÙÙ
ÙØ¶Ø¹ `start` ÙØ§ÙÙ
ÙØ¶Ø¹ `end` | ØºÙØ± Ù
سÙ
ÙØØ© ÙØªØµØ¨Ø `0` |
| `substr(start, length)â` | أرجع Ø§ÙØ£ØØ±Ù بطÙÙ `length` Ø¨Ø¯Ø¡ÙØ§ Ù
Ù `start` | Ù
سÙ
ÙØØ© ÙÙÙ
عاÙ
Ù `start` |
+=======
+ This method resides in the [Annex B](https://tc39.es/ecma262/#sec-string.prototype.substr) of the language specification. It means that only browser-hosted Javascript engines should support it, and it's not recommended to use it. In practice, it's supported everywhere.
+Let's recap these methods to avoid any confusion:
+| method | selects... | negatives |
+|--------|-----------|-----------|
+| `slice(start, end)` | from `start` to `end` (not including `end`) | allows negatives |
+| `substring(start, end)` | between `start` and `end` (not including `end`)| negative values mean `0` |
+| `substr(start, length)` | from `start` get `length` characters | allows negative `start` |
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
+
+
+<<<<<<< HEAD
```smart header="**Ø£ÙÙÙ
ا تختارØ**"
ÙÙ
ÙÙ ÙØ¬Ù
ÙØ¹ Ø§ÙØªÙابع تÙÙÙØ° Ø§ÙØºØ±Ø¶ اÙÙ
Ø·ÙÙØ¨. ÙØ¯Ù Ø§ÙØªØ§Ø¨Ø¹ `substr` ÙØµÙر Ø¨Ø³ÙØ· رسÙ
ÙÙØ§: ÙÙÙ ØºÙØ± ذÙÙØ±Ø© ÙÙ ØªÙØ«ÙÙ JavaScript Ø§ÙØ±Ø³Ù
ÙØ ب٠ÙÙ Annex B ÙØ§ÙØ°Ù ÙØºØ·Ù Ù
ÙØ²Ø§Øª Ù
دعÙÙ
Ø© Ù٠اÙÙ
ØªØµÙØØ§Øª ÙÙØ· ÙØ£Ø³Ø¨Ø§Ø¨ ØªØ§Ø±ÙØ®ÙØ©Ø ÙØ°Ø§ ÙØ¥Ù Ø£Ù Ø¨ÙØ¦Ø© ÙØ§ تعÙ
٠عÙ٠اÙÙ
ØªØµÙØ Ø³ØªÙØ´Ù Ù٠دعÙ
ÙØ°Ø§ Ø§ÙØªØ§Ø¨Ø¹Ø ÙÙÙÙ ÙØ¹Ù
٠عÙ
ÙÙÙØ§ ÙÙ ÙÙ Ù
ÙØ§Ù.
Ù
ا بÙÙ Ø§ÙØ®ÙارÙÙ Ø§ÙØ¢Ø®Ø±ÙÙØ `slice` ÙÙ Ø£ÙØ«Ø± Ù
رÙÙØ©Ø ÙÙÙ ÙØ³Ù
Ø Ø¨ØªÙ
Ø±ÙØ± Ù
ÙØ¹Ø§Ù
ÙÙØ§Øª Ø³Ø§ÙØ¨Ø© ÙÙ
ا Ø£ÙÙ Ø£ÙØµØ± Ù٠اÙÙØªØ§Ø¨Ø©. ÙØ°Ø§Ø Ù
٠اÙÙØ§ÙÙ ØªØ°ÙØ± `slice` ÙÙØ· Ù
Ù ÙØ°Ù Ø§ÙØªÙابع Ø§ÙØ«Ùاث.
+=======
+Of the other two variants, `slice` is a little bit more flexible, it allows negative arguments and shorter to write.
+
+So, for practical use it's enough to remember only `slice`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
## Ù
ÙØ§Ø²ÙØ© اÙÙØµÙص
@@ -485,6 +558,7 @@ There are 3 methods in JavaScript to get a substring: `substring`, `substr` and
ÙØ¯ ÙÙÙØ¯ ذÙ٠إÙÙ ÙØªØ§Ø¦Ø¬ ØºØ±ÙØ¨Ø© Ø¥Ù Ø±ØªØ¨ÙØ§ Ù
Ø«ÙÙØ§ بÙ٠أسÙ
اء Ø¨ÙØ¯Ø§ÙØ ÙÙØªÙÙØ¹ اÙÙØ§Ø³ دائÙ
ÙØ§ Ø£Ù `Zealand` تأت٠بعد `Ãsterreich` Ù٠اÙÙØ§Ø¦Ù
Ø© ÙØ£Ù تÙÙØ³ ØªØ£ØªÙ ÙØ¨Ù Ø³ÙØ±Ùا ÙÙÙØ°Ø§. ÙÙÙÙ
Ù
ا ÙØØ¯Ø«Ø ÙÙØ±Ø§Ø¬Ø¹ تÙ
Ø«Ù٠اÙÙØµÙص Ø§ÙØ¯Ø§Ø®ÙÙ ÙÙ JavaScript.
+<<<<<<< HEAD
جÙ
ÙØ¹ اÙÙØµÙص Ù
Ø´ÙØ±Ø© باستخداÙ
[UTF-16](https://en.wikipedia.org/wiki/UTF-16). ÙØ¹Ù٠أÙ: ÙÙÙ ØØ±Ù رÙ
ز عدد٠Ù
ÙØ§Ø¨Ù ÙÙ. ÙÙØ¬Ø¯ Ø¯ÙØ§Ù خاصة تسÙ
Ø Ø¨Ø§ÙØØµÙ٠عÙÙ Ø§ÙØØ±Ù Ù
٠رÙ
Ø²Ù ÙØ§ÙØ¹ÙØ³.
### **`str.codePointAt(pos)â`**
@@ -494,7 +568,20 @@ There are 3 methods in JavaScript to get a substring: `substring`, `substr` and
```js run
// ÙØ¯Ù Ø§ÙØ£ØØ±Ù اÙÙ
ختÙÙØ© ÙÙ Ø§ÙØØ§ÙØ© رÙ
ÙØ² Ù
ختÙÙØ©
alert( "z".codePointAt(0) ); // 122
+=======
+To understand what happens, we should be aware that strings in Javascript are encoded using [UTF-16](https://en.wikipedia.org/wiki/UTF-16). That is: each character has a corresponding numeric code.
+
+There are special methods that allow to get the character for the code and back:
+
+`str.codePointAt(pos)`
+: Returns a decimal number representing the code for the character at position `pos`:
+
+ ```js run
+ // different case letters have different codes
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
alert( "Z".codePointAt(0) ); // 90
+ alert( "z".codePointAt(0) ); // 122
+ alert( "z".codePointAt(0).toString(16) ); // 7a (if we need a hexadecimal value)
```
### **`String.fromCodePoint(code)â`**
@@ -503,6 +590,7 @@ There are 3 methods in JavaScript to get a substring: `substring`, `substr` and
```js run
alert( String.fromCodePoint(90) ); // Z
+<<<<<<< HEAD
```
We can also add Unicode characters by their codes using `\u` followed by the hex code:
@@ -510,6 +598,9 @@ There are 3 methods in JavaScript to get a substring: `substring`, `substr` and
```js run
// ÙÙÙ
Ø«ÙÙÙ Ø§ÙØ¹Ø¯Ø¯ Ø§ÙØ¹Ø´Ø±Ù 90 Ø¨Ø§ÙØ¹Ø¯Ø¯ 5a Ù٠اÙÙØ¸Ø§Ù
Ø§ÙØ³Øª عشرÙ.
alert( '\u005a' ); // Z
+=======
+ alert( String.fromCodePoint(0x5a) ); // Z (we can also use a hex value as an argument)
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
ÙÙØ±Ù Ø§ÙØ¢Ù Ø§ÙØ£ØØ±Ù ذات Ø§ÙØ±Ù
ÙØ² `65..220` (Ø§ÙØ£ØØ±Ù اÙÙØ§ØªÙÙÙØ© ÙØ£Ø´Ùاء إضاÙÙØ©) عبر Ø¥ÙØ´Ø§Ø¡ ÙØµÙص Ù
ÙÙØ§:
@@ -521,6 +612,7 @@ for (let i = 65; i <= 220; i++) {
str += String.fromCodePoint(i);
}
alert( str );
+// Output:
// ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÂÂÂÂÂ
// ¡¢£¤¥¦§¨©ª«¬Â®¯°±²³´µ¶·¸¹º»¼½¾¿ÃÃÃÃÃÃ
ÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃ
```
@@ -532,14 +624,23 @@ alert( str );
- ØªØ£ØªÙ Ø§ÙØ£ØØ±Ù Ø§ÙØµØºÙرة بعد Ø§ÙØ£ØØ±Ù اÙÙØ¨Ùرة دائÙ
ÙØ§ ÙØ£Ù رÙ
ÙØ²Ùا Ø§ÙØ¹Ø¯Ø¯ÙØ© دائÙ
ÙØ§ Ø£ÙØ¨Ø±.
- تÙÙ٠بعض Ø§ÙØ£ØØ±Ù Ù
ث٠`Ã` Ø¨Ø¹ÙØ¯Ø© Ø¹Ù Ø§ÙØ£ØØ±Ù اÙÙØ¬Ø§Ø¦ÙØ©. ÙÙØ§Ø ÙÙÙ
Ø© Ø§ÙØØ±Ù ÙØ°Ø§ Ø£ÙØ¨Ø± Ù
Ù Ø£Ù ØØ±Ù بÙÙ `a` Ù `z`.
+<<<<<<< HEAD
### Ù
ÙØ§Ø²Ùات صØÙØØ©
+=======
+- All lowercase letters go after uppercase letters because their codes are greater.
+- Some letters like `Ã` stand apart from the main alphabet. Here, its code is greater than anything from `a` to `z`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
### Correct comparisons [#correct-comparisons]
ÙØØ³Ù Ø§ÙØØ¸Ø ØªØ¯Ø¹Ù
جÙ
ÙØ¹ اÙÙ
ØªØµÙØØ§Øª Ø§ÙØØ¯ÙØ«Ø© اÙÙ
Ø¹ÙØ§Ø± Ø§ÙØ¹Ø§ÙÙ
Ù [ECMA 402](http://www.ecma-international.org/ecma-402/1.0/ECMA-402.pdf)(IE10- Ø§ÙØ°Ù ÙØªØ·Ùب اÙÙ
ÙØªØ¨Ø© Ø§ÙØ§Ø¶Ø§ÙÙØ© [Intl.JS](https://github.com/andyearnshaw/Intl.js/))Ø Ø¥Ø° ÙÙÙØ± ØªØ§Ø¨Ø¹ÙØ§ Ø®Ø§ØµÙØ§ ÙÙ
ÙØ§Ø²ÙØ© اÙÙØµÙص Ø¨ÙØºØ§Øª Ù
ØªØ¹Ø¯Ø¯Ø©Ø ÙÙÙÙØ§ ÙÙÙØ§Ø¹Ø¯Ùا.
+<<<<<<< HEAD
ÙÙØ±Ø¬Ùع استدعاء Ø§ÙØªØ§Ø¨Ø¹ [`str.localeCompare(str2)â`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare) Ø¹Ø¯Ø¯ÙØ§ ÙØØ¯Ø¯ Ù
ا Ø¥Ù ÙØ§Ù اÙÙØµ `str` Ø£ØµØºØ±Ø Ø£Ù ÙØ³Ø§ÙÙØ Ø£Ù Ø£ÙØ¨Ø± Ù
٠اÙÙØµ `str2` ÙÙÙÙØ§ ÙÙÙØ§Ø¹Ø¯ اÙÙØºØ© اÙÙ
ØÙÙØ©:
+=======
+Luckily, modern browsers support the internationalization standard [ECMA-402](https://www.ecma-international.org/publications-and-standards/standards/ecma-402/).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
- ÙÙØ±Ø¬Ùع ÙÙÙ
Ø© Ø³Ø§ÙØ¨Ø© Ø¥Ù ÙØ§Ù `str` أصغر Ù
Ù `str2`.
- ÙÙØ±Ø¬Ùع ÙÙÙ
Ø© Ù
ÙØ¬Ø¨Ø© Ø¥Ù ÙØ§Ù `str` Ø£ÙØ¨Ø± Ù
Ù `str2`.
@@ -555,6 +656,7 @@ mdn:js/String/localeCompare
ÙÙ Ø§ÙØÙÙÙØ©Ø ÙÙØ°Ù Ø§ÙØ¯Ø§ÙØ© Ù
ÙØ¹Ø§Ù
ÙÙÙ٠إضاÙÙÙÙ ÙÙ
ا ÙÙ [ØªÙØ«ÙÙÙØ§ عÙÙ MDN](mdn:js/String/localeCompare)Ø Ø¥Ø° ÙØ³Ù
Ø ÙØ°Ø§Ù اÙÙ
ÙØ¹Ø§Ù
ÙØ§Ù Ø¨ØªØØ¯Ùد اÙÙØºØ© (تؤخذ Ù
Ù Ø¨ÙØ¦Ø© Ø§ÙØ¹Ù
٠تÙÙØ§Ø¦ÙÙØ§Ø ÙÙØ¹ØªÙ
د ØªØ±ØªÙØ¨ Ø§ÙØ£ØØ±Ù عÙ٠اÙÙØºØ©) Ø¨Ø§ÙØ¥Ø¶Ø§ÙØ© Ø¥Ù٠إعداد ÙÙØ§Ø¹Ø¯ أخر٠Ù
Ø«Ù Ø§ÙØØ³Ø§Ø³ÙØ© ØªØ¬Ø§Ù ØØ§ÙØ© Ø§ÙØ£ØØ±ÙØ Ø£Ù Ù
ا Ø¥Ù ÙØ§Ù ÙØ¬Ø¨ Ù
عاÙ
ÙØ© `"a"` Ù `"aÌ"` Ø¨Ø§ÙØ·Ø±ÙÙØ© ÙÙØ³Ùا ...Ø§ÙØ®.
+<<<<<<< HEAD
## Ù
ا Ø®ÙÙ Ø§ÙØ³ØªØ§Ø±Ø ÙÙÙÙÙÙØ¯
```warn header="**Ù
عÙÙÙ
ات Ù
ØªÙØ¯Ù
Ø©**"
@@ -667,11 +769,13 @@ alert( "S\u0307\u0323".normalize() == "\u1e68" ); // true
إ٠أردت تعÙÙ
اÙÙ
Ø²ÙØ¯ ع٠ÙÙØ§Ø¹Ø¯ Ø§ÙØªÙØÙد ÙØ§Ø®ØªÙØ§ÙØ§ØªÙا - ÙØ³ØªØ¬Ø¯Ùا ÙÙ Ù
ÙØÙ Ù
عاÙÙØ± اÙÙÙÙÙÙÙØ¯: [ÙÙ
اذج ØªÙØÙØ¯ ترÙ
ÙØ² اÙÙÙÙÙÙÙØ¯](http://www.unicode.org/reports/tr15/), ÙÙÙ ÙÙØ£ØºØ±Ø§Ø¶ Ø§ÙØ¹Ù
ÙÙØ© اÙÙ
ØªØ¹Ø§Ø±ÙØ© ÙØ§ÙÙ
عÙÙÙ
ات Ø§ÙØ³Ø§Ø¨ÙØ© تÙÙ Ø¨Ø§ÙØºØ±Ø¶.
## اÙÙ
ÙÙØ®Øµ
+=======
+## Summary
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
- There are 3 types of quotes. Backticks allow a string to span multiple lines and embed expressions `${â¦}`.
-- Strings in JavaScript are encoded using UTF-16.
-- We can use special characters like `\n` and insert letters by their Unicode using `\u...`.
-- To get a character, use: `[]`.
+- We can use special characters, such as a line break `\n`.
+- To get a character, use: `[]` or `at` method.
- To get a substring, use: `slice` or `substring`.
- To lowercase/uppercase a string, use: `toLowerCase/toUpperCase`.
- To look for a substring, use: `indexOf`, or `includes/startsWith/endsWith` for simple checks.
@@ -683,4 +787,10 @@ alert( "S\u0307\u0323".normalize() == "\u1e68" ); // true
- `str.repeat(n)â ` تÙÙØ±ÙÙØ± اÙÙØµ `n` Ù
رة.
- ÙØ§ÙÙ
Ø²ÙØ¯Ø ÙÙ
ÙÙ Ø§ÙØ§Ø·Ùاع عÙÙÙØ§ ÙÙ [manual](mdn:js/String).
+<<<<<<< HEAD
ÙÙØ§ÙÙ ØªÙØ§Ø¨Ø¹ أخر٠ÙÙÙØµÙص Ø£ÙØ¶Ùا تعÙ
٠عÙÙ Ø§ÙØ¨ØØ«/Ø§ÙØ§Ø³ØªØ¨Ø¯Ø§Ù Ù
ع Ø§ÙØªØ¹Ø§Ø¨Ùر اÙÙÙ
Ø·ÙØ© (regular expressions). ÙÙ٠ذÙÙ Ù
ÙØ¶Ùع ÙØ¨ÙØ±Ø ÙØ°Ø§ ÙÙØ¯ Ø´ÙØ±ÙØÙ ÙÙ ÙØµÙ Ù
ستÙÙØ .
+=======
+Strings also have methods for doing search/replace with regular expressions. But that's big topic, so it's explained in a separate tutorial section .
+
+Also, as of now it's important to know that strings are based on Unicode encoding, and hence there're issues with comparisons. There's more about Unicode in the chapter .
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md
index e646cb605..1b15f5dbf 100644
--- a/1-js/05-data-types/04-array/10-maximal-subarray/solution.md
+++ b/1-js/05-data-types/04-array/10-maximal-subarray/solution.md
@@ -57,7 +57,11 @@ alert(getMaxSubSum([100, -9, 2, -3, 5])); // 100
The solution has a time complexity of [O(n2)](https://en.wikipedia.org/wiki/Big_O_notation). In other words, if we increase the array size 2 times, the algorithm will work 4 times longer.
+<<<<<<< HEAD
# Ø§ÙØÙ Ø§ÙØ£Ø³Ø±Ø¹
+=======
+For big arrays (1000, 10000 or more items) such algorithms can lead to serious sluggishness.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¯Ø¹ÙØ§ ÙØ³Ùر Ù٠اÙÙ
صÙÙÙØ© ÙÙØØªÙØ¸ باÙÙ
جÙ
ÙØ¹ Ø§ÙØ¬Ø²Ø¦Ù Ø§ÙØØ§ÙÙ ÙÙØ¹Ùاصر Ù٠اÙÙ
ØªØºÙØ± `s`. إذا Ø£ØµØ¨ØØª `s` Ø³Ø§ÙØ¨Ø© ÙÙ ÙÙØª Ù
ا Ø ÙÙ
بتعÙÙÙ` s = 0`. سÙÙÙÙ Ø§ÙØØ¯ Ø§ÙØ£Ùص٠ÙÙÙ ÙØ°Ù Ø§ÙØ¥Ø¬Ø§Ø¨Ø§Øª ÙÙ Ø§ÙØ¥Ø¬Ø§Ø¨Ø©.
@@ -88,4 +92,8 @@ alert(getMaxSubSum([-1, -2, -3])); // 0
ØªØªØ·ÙØ¨ Ø§ÙØ®ÙارزÙ
ÙØ© تÙ
Ø±ÙØ±Ø§Ù Ù
صÙÙÙÙ ÙØ§ØØ¯Ù Ø ÙØ°Ø§ ÙØ¥Ù تعÙÙØ¯ اÙÙÙØª ÙÙ O (n).
+<<<<<<< HEAD
ÙÙ
ÙÙÙ Ø§ÙØ¹Ø«Ùر عÙÙ Ù
Ø²ÙØ¯ Ù
٠اÙÙ
عÙÙÙ
ات Ø§ÙØªÙصÙÙÙØ© ØÙÙ Ø§ÙØ®ÙارزÙ
ÙØ© ÙÙØ§: [Maximum subarray problem](http://en.wikipedia.org/wiki/Maximum_subarray_problem). إذا ÙØ§Ù ÙØ§ ÙØ²Ø§Ù Ù
Ù ØºÙØ± اÙÙØ§Ø¶Ø سبب ÙØ¬Ø§Ø ذÙÙ Ø ÙØ§Ùرجاء تتبع Ø§ÙØ®ÙارزÙ
ÙØ© ÙÙ Ø§ÙØ£Ù
Ø«ÙØ© Ø£Ø¹ÙØ§Ù Ø ÙÙ
Ø¹Ø±ÙØ© ÙÙÙÙØ© عÙ
ÙÙØ§ Ø ÙÙØ°Ø§ Ø£ÙØ¶Ù Ù
٠أ٠ÙÙÙ
ات.
+=======
+You can find more detailed information about the algorithm here: [Maximum subarray problem](http://en.wikipedia.org/wiki/Maximum_subarray_problem). If it's still not obvious why that works, then please trace the algorithm on the examples above, see how it works, that's better than any words.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/05-data-types/04-array/2-create-array/task.md b/1-js/05-data-types/04-array/2-create-array/task.md
index f51ce7c05..063928a67 100644
--- a/1-js/05-data-types/04-array/2-create-array/task.md
+++ b/1-js/05-data-types/04-array/2-create-array/task.md
@@ -6,11 +6,21 @@
ÙÙØ§ ÙØ¬Ø±Ø¨ 5 Ù
عاÙ
ÙØ§Øª ÙÙÙ
صÙÙÙÙ.
+<<<<<<< HEAD
1. ÙÙ
Ø¨Ø§ÙØ´Ø§Ø¡ Ø¹Ø¯Ù Ø¹ÙØ§ØµØ± `styles` "Ù
ÙØ³ÙÙÙ Ø§ÙØ¬Ø§Ø²" Ù "Ø§ÙØ¨ÙÙØ²" .
2. اض٠Ù٠اÙÙÙØ§ÙÙ" Ù
ÙØ³ÙÙÙ Ø§ÙØ±ÙÙ Ø¢ÙØ¯ رÙÙ"
3. استبد٠اÙÙÙÙ
Ø© Ù٠اÙÙ
ÙØªØµÙ ب٠"ÙÙØ§Ø³ÙÙÙØ§Øª". ÙØ¬Ø¨ Ø§Ù ÙØ¹Ù
٠اÙÙÙØ¯ Ø§ÙØ®Ø§Øµ ب٠ÙÙØ¹Ø«Ùر عÙ٠اÙÙÙÙ
Ø© اÙÙØ³Ø·Ù ÙØ£Ù Ù
صÙÙÙ٠ذات Ø·ÙÙ ÙØ±Ø¯Ù.
4. ØªØ¬Ø±ÙØ¯ اÙÙÙÙ
Ø© Ø§ÙØ£ÙÙÙ Ù
Ù Ù
صÙÙÙÙ ÙØ¥Ø¸ÙØ§Ø±ÙØ§.
5. استعد `Rap` Ù `Reggae` اÙ٠اÙÙ
صÙÙÙÙ .
+=======
+1. Create an array `styles` with items "Jazz" and "Blues".
+2. Append "Rock-n-Roll" to the end.
+3. Replace the value in the middle with "Classics". Your code for finding the middle value should work for any arrays with odd length.
+4. Strip off the first value of the array and show it.
+5. Prepend `Rap` and `Reggae` to the array.
+
+The array in the process:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
اÙÙ
صÙÙÙÙ ÙÙ Ø§ÙØ¹Ù
ÙÙÙ :
```js no-beautify
diff --git a/1-js/05-data-types/04-array/3-call-array-this/task.md b/1-js/05-data-types/04-array/3-call-array-this/task.md
index 2910d2b31..80d828491 100644
--- a/1-js/05-data-types/04-array/3-call-array-this/task.md
+++ b/1-js/05-data-types/04-array/3-call-array-this/task.md
@@ -11,7 +11,7 @@ let arr = ["a", "b"];
arr.push(function() {
alert( this );
-})
+});
arr[2](); // ?
```
diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md
index 29a027ded..26b70c07f 100644
--- a/1-js/05-data-types/04-array/article.md
+++ b/1-js/05-data-types/04-array/article.md
@@ -90,6 +90,38 @@ let fruits = [
ÙØ³ÙÙÙ ÙÙ
Ø· "اÙÙØ§ØµÙØ© اÙÙØ§ØÙØ©" إدراج / Ø¥Ø²Ø§ÙØ© Ø§ÙØ¹Ùاصر Ø ÙØ£Ù جÙ
ÙØ¹ Ø§ÙØ®Ø·ÙØ· Ù
ØªØ´Ø§Ø¨ÙØ©.````
+## Get last elements with "at"
+
+[recent browser="new"]
+
+Let's say we want the last element of the array.
+
+Some programming languages allow the use of negative indexes for the same purpose, like `fruits[-1]`.
+
+However, in JavaScript it won't work. The result will be `undefined`, because the index in square brackets is treated literally.
+
+We can explicitly calculate the last element index and then access it: `fruits[fruits.length - 1]`.
+
+```js run
+let fruits = ["Apple", "Orange", "Plum"];
+
+alert( fruits[fruits.length-1] ); // Plum
+```
+
+A bit cumbersome, isn't it? We need to write the variable name twice.
+
+Luckily, there's a shorter syntax: `fruits.at(-1)`:
+
+```js run
+let fruits = ["Apple", "Orange", "Plum"];
+
+// same as fruits[fruits.length-1]
+alert( fruits.at(-1) ); // Plum
+```
+
+In other words, `arr.at(i)`:
+- is exactly the same as `arr[i]`, if `i >= 0`.
+- for negative values of `i`, it steps back from the end of the array.
## ÙØ³Ø§Ø¦Ù pop/push, shift/unshift
@@ -117,9 +149,15 @@ let fruits = [
باÙÙØ³Ø¨Ù ÙÙÙÙÙ
Ù(stacks), ÙØªÙ
Ø§Ø³ØªÙØ§Ù
Ø£ØØ¯Ø« Ø¹ÙØµØ± Ù
دÙÙØ¹ Ø£ÙÙØ§Ù Ø ÙÙØ°Ø§ Ù
ا ÙØ³Ù
٠بÙ
بدأ LIFO (Last-In-First-Out). باÙÙØ³Ø¨Ø© ÙÙÙØ§Ø¦Ù
Ø§ÙØ§Ùتظار Ø ÙØ¯ÙÙØ§ FIFO (First-In-First-Out).
+<<<<<<< HEAD
ÙÙ
Ù٠أ٠تعÙ
٠اÙÙ
صÙÙÙØ§Øª ÙÙ JavaScript ÙÙØ§Ø¦Ù
Ø© Ø§ÙØªØ¸Ø§Ø± ÙÙÙ
جÙ
ÙØ¹Ø©(stack). ØªØªÙØ ÙÙ Ø¥Ø¶Ø§ÙØ© / Ø¥Ø²Ø§ÙØ© Ø¹ÙØ§ØµØ± Ù
Ù / Ø¥ÙÙ Ø§ÙØ¨Ø¯Ø§ÙØ© أ٠اÙÙÙØ§ÙØ©.
Ù٠عÙÙ
Ø§ÙØØ§Ø³ÙØ¨ ÙØ³Ù
Ù ÙÙÙÙ Ø§ÙØ¨ÙØ§ÙØ§Øª Ø§ÙØ°Ù ÙØ³Ù
Ø Ø¨Ø°ÙÙ [deque](https://en.wikipedia.org/wiki/Double-ended_queue).
+=======
+Arrays in JavaScript can work both as a queue and as a stack. They allow you to add/remove elements, both to/from the beginning or the end.
+
+In computer science, the data structure that allows this, is called [deque](https://en.wikipedia.org/wiki/Double-ended_queue).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
**Ø§ÙØ£Ø³Ø§ÙÙØ¨ Ø§ÙØªÙ تعÙ
Ù Ù
ع ÙÙØ§ÙØ© اÙÙ
صÙÙÙÙ:**
@@ -134,6 +172,8 @@ let fruits = [
;alert( fruits ) // Ø§ÙØ¨Ø±ØªÙاÙ, Ø§ÙØªÙاØ
```
+ Both `fruits.pop()` and `fruits.at(-1)` return the last element of the array, but `fruits.pop()` also modifies the array by removing it.
+
`push`
: Ø£ÙØÙ Ø§ÙØ¹Ùصر بÙÙØ§ÙØ© اÙÙ
صÙÙÙØ©:
@@ -240,7 +280,11 @@ fruits.age = 25; // Ø£ÙØ´Ø¦ Ø§ÙØ®Ø§ØµÙ٠باسÙ
Ø§ÙØªØ±Ø§Ø¶Ù
fruits.shift(); // ÙÙ
بأخذ Ø¹ÙØµØ± Ù
Ù Ø§ÙØ¨Ø¯Ø§ÙÙ
```
+<<<<<<< HEAD
ÙØ§ ÙÙÙ٠أخذ Ø§ÙØ¹Ùصر ÙØ¥Ø²Ø§ÙØªÙ Ø¨Ø§ÙØ±ÙÙ
`0`.ÙØ¬Ø¨ إعادة ترÙÙÙ
Ø§ÙØ¹Ùاصر Ø§ÙØ£Ø®Ø±Ù Ø£ÙØ¶Ùا.
+=======
+It's not enough to take and remove the element with the index `0`. Other elements need to be renumbered as well.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
`shift` ÙØ°Ù Ø§ÙØ¹Ù
ÙÙÙ ÙØ¬Ø¨ Ø§Ù ØªÙØ¹Ù 3 Ø£Ø´ÙØ§Ø¡:
@@ -357,11 +401,19 @@ alert( arr[3] ); // ØºÙØ±Ù
عرÙ: ÙØ°Ø§Ù٠اÙÙÙÙ
Ù٠تعد
let arr = *!*new Array*/!*("Ø§ÙØ®", "اÙÙÙ
ثرÙ", "Ø§ÙØªÙاØ");
```
+<<<<<<< HEAD
ÙØ§Ø¯Ø±Ùا Ù
ا ÙØªÙ
استخداÙ
Ù Ø ÙØ£Ù Ø§ÙØ£ÙÙØ§Ø³ اÙÙ
ربعة `[] Ø£ÙØµØ±. Ø£ÙØ¶Ø§ ÙÙØ§Ù Ù
ÙØ²Ø© صعبة Ù
Ø¹ÙØ§.
+=======
+It's rarely used, because square brackets `[]` are shorter. Also, there's a tricky feature with it.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
إذا تÙ
استدعاء `Ù
صÙÙÙÙ Ø¬Ø¯ÙØ¯Ù` باستخداÙ
ÙØ³ÙÙÙ ÙØ§ØØ¯Ø© عبارة ع٠رÙÙ
Ø ÙØ¥ÙÙ ÙÙØ´Ø¦ Ù
صÙÙÙØ© * بدÙÙ Ø¹ÙØ§ØµØ± Ø ÙÙÙÙ Ø¨Ø§ÙØ·Ù٠اÙÙ
ØØ¯Ø¯ *.
+<<<<<<< HEAD
دعÙÙØ§ ÙØ±Ù ÙÙÙ ÙÙ
ÙÙ ÙÙÙ
رء Ø£Ù ÙØ·Ù٠اÙÙØ§Ø± عÙÙ ÙØ¯Ù
Ù:
+=======
+Let's see how one can shoot themselves in the foot:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let arr = new Array(2); //Ù٠سÙÙØ´Ø¦ Ù
صÙÙÙÙ Ù
ÙÙÙÙ Ù
Ù [2] ?
@@ -371,9 +423,13 @@ alert( arr[0] ); // ØºÙØ± Ù
عرÙ! ÙØ§ ØªÙØ¬Ø¯ Ø¹ÙØ§ØµØ±.
alert( arr.length ); // Ø§ÙØ·ÙÙ 2
```
+<<<<<<< HEAD
Ù٠اÙÙÙØ¯ Ø£Ø¹ÙØ§Ù, `Ù
صÙÙÙÙ Ø¬Ø¯ÙØ¯Ù(رÙÙ
)` تÙÙÙ ÙØ¯ÙÙØ§ ÙÙ Ø§ÙØ¹Ùاصر `ØºÙØ± Ù
عرÙÙ`.
ÙÙØªÙرب Ù
Ù ÙØ°Ù اÙÙ
ÙØ§Ø¬Ø¢Øª Ø ÙØ³ØªØ®Ø¯Ù
Ø¹Ø§Ø¯Ø©Ù Ø§ÙØ£ÙÙØ§Ø³ اÙÙ
ربعة Ø Ø¥ÙØ§ إذا ÙÙØ§ ÙØ¹Ø±Ù ØÙÙØ§ Ù
ا ÙÙÙÙ
بÙ.
+=======
+To avoid such surprises, we usually use square brackets, unless we really know what we're doing.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## Ù
صÙÙÙØ§Øª Ù
ØªØ¹Ø¯Ø¯Ù Ø§ÙØ£Ø¨Ø¹Ø§Ø¯
@@ -386,7 +442,11 @@ let matrix = [
[7, 8, 9]
];
+<<<<<<< HEAD
alert( matrix[1][1] ); // 5, Ø§ÙØ¹Ùصر اÙÙ
Ø±ÙØ²Ù
+=======
+alert( matrix[0][1] ); // 2, the second value of the first inner array
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
## Ø§ÙØªØÙÙ٠إÙÙ ÙØµ
@@ -432,7 +492,7 @@ Let's recall the rules:
- If one of the arguments of `==` is an object, and the other one is a primitive, then the object gets converted to primitive, as explained in the chapter .
- ...With an exception of `null` and `undefined` that equal `==` each other and nothing else.
-The strict comparison `===` is even simpler, as it doesn't convert types.
+The strict comparison `===` is even simpler, as it doesn't convert types.
So, if we compare arrays with `==`, they are never the same, unless we compare two variables that reference exactly the same array.
@@ -452,7 +512,7 @@ alert( 0 == [] ); // true
alert('0' == [] ); // false
```
-Here, in both cases, we compare a primitive with an array object. So the array `[]` gets converted to primitive for the purpose of comparison and becomes an empty string `''`.
+Here, in both cases, we compare a primitive with an array object. So the array `[]` gets converted to primitive for the purpose of comparison and becomes an empty string `''`.
Then the comparison process goes on with the primitives, as described in the chapter :
@@ -471,6 +531,7 @@ That's simple: don't use the `==` operator. Instead, compare them item-by-item i
اÙÙ
صÙÙÙØ§Øª ÙÙ ÙÙØ¹ خاص Ù
٠اÙÙØ§Ø¦Ùات Ø Ù
ÙØ§Ø³Ø¨ ÙØªØ®Ø²ÙÙ ÙØ¥Ø¯Ø§Ø±Ø© Ø¹ÙØ§ØµØ± Ø§ÙØ¨ÙØ§ÙØ§Øª اÙÙ
Ø·ÙÙØ¨Ø©.
+<<<<<<< HEAD
- Ø§ÙØ¥Ø¹ÙاÙ:
```js
@@ -482,11 +543,33 @@ That's simple: don't use the `==` operator. Instead, compare them item-by-item i
```
ÙØ¤Ø¯Ù استدعاء "Ù
صÙÙÙÙ Ø¬Ø¯ÙØ¯Ù (رÙÙ
) " Ø¥ÙÙ Ø¥ÙØ´Ø§Ø¡ Ù
صÙÙÙØ© بطÙÙ Ù
عÙÙ Ø ÙÙÙ٠بدÙÙ Ø¹ÙØ§ØµØ±..
+=======
+The declaration:
+
+```js
+// square brackets (usual)
+let arr = [item1, item2...];
+
+// new Array (exceptionally rare)
+let arr = new Array(item1, item2...);
+```
+
+The call to `new Array(number)` creates an array with the given length, but without elements.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
- Ø§ÙØ®Ø§ØµÙØ© `length` ÙÙ Ø·Ù٠اÙÙ
صÙÙÙØ© Ø£Ù Ø Ø¹ÙÙ ÙØ¬Ù Ø§ÙØ¯ÙØ© Ø Ø¢Ø®Ø± ÙÙØ±Ø³ رÙÙ
Ù Ø¨Ø§ÙØ¥Ø¶Ø§ÙØ© Ø¥ÙÙ ÙØ§ØØ¯. ÙØªÙ
ضبط٠تÙÙØ§Ø¦ÙÙØ§ Ø¨ÙØ§Ø³Ø·Ø© طر٠ÙÙÙ
صÙÙÙÙ.
- إذا Ø§Ø®ØªØµØ±ÙØ§ "Ø§ÙØ·ÙÙ" ÙØ¯ÙÙÙØ§ Ø ÙØ³ÙتÙ
Ø§ÙØªØ·Ø§Ø¹ اÙÙ
صÙÙÙØ©.
+<<<<<<< HEAD
ÙÙ
ÙÙÙØ§ استخداÙ
Ù
صÙÙÙØ© ÙÙ
ادة Ù
ع Ø§ÙØ¹Ù
ÙÙØ§Øª Ø§ÙØªØ§ÙÙØ©:
+=======
+Getting the elements:
+
+- we can get element by its index, like `arr[0]`
+- also we can use `at(i)` method that allows negative indexes. For negative values of `i`, it steps back from the end of the array. If `i >= 0`, it works same as `arr[i]`.
+
+We can use an array as a deque with the following operations:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
- `push(...Ø¹ÙØ§ØµØ±)`تضÙÙ `Ø§ÙØ¹Ùاصر` Ø¥Ù٠اÙÙÙØ§ÙØ©.
- `pop()`Ø¥Ø²Ø§ÙØ© Ø§ÙØ¹Ùصر Ù
٠اÙÙÙØ§ÙØ© ÙØ¥Ø¹Ø§Ø¯ØªÙ.
diff --git a/1-js/05-data-types/05-array-methods/12-reduce-object/task.md b/1-js/05-data-types/05-array-methods/12-reduce-object/task.md
index f89f17263..a44d3e8a9 100644
--- a/1-js/05-data-types/05-array-methods/12-reduce-object/task.md
+++ b/1-js/05-data-types/05-array-methods/12-reduce-object/task.md
@@ -4,7 +4,11 @@ importance: 4
# Ø§ÙØ´Ø§Ø¡ Ù
ÙØ§ØªÙØ Ø®Ø§ØµØ© Ø¨ÙØ§Ø¦Ùات اÙÙ
صÙÙÙØ©
+<<<<<<< HEAD
Ø¯Ø¹ÙØ§ ÙÙÙ٠أÙÙØ§ ÙØ³ØªÙب٠Ù
صÙÙÙØ© خاصة باÙÙ
ستخدÙ
Ù٠داخ٠form Ù
ÙÙÙØ© `{id:..., name:..., age... }`
+=======
+Let's say we received an array of users in the form `{id:..., name:..., age:... }`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø§ÙØªØ¨ Ø¯Ø§ÙØ© `groupById(arr)` ÙØ§Ùشاء ÙØ§Ø¦Ù Ù
ÙÙØ§ ÙØØªÙ٠عÙÙ `id` ÙÙ
ÙØªØ§Ø Ù Ø¹ÙØ§ØµØ± اÙÙ
صÙÙÙØ© ÙÙÙÙ
diff --git a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js
index db32d9a11..241b74c6e 100644
--- a/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js
+++ b/1-js/05-data-types/05-array-methods/3-filter-range-in-place/_js.view/test.js
@@ -4,13 +4,13 @@ describe("filterRangeInPlace", function() {
let arr = [5, 3, 8, 1];
- filterRangeInPlace(arr, 1, 4);
+ filterRangeInPlace(arr, 2, 5);
- assert.deepEqual(arr, [3, 1]);
+ assert.deepEqual(arr, [5, 3]);
});
it("doesn't return anything", function() {
assert.isUndefined(filterRangeInPlace([1,2,3], 1, 4));
});
-});
\ No newline at end of file
+});
diff --git a/1-js/05-data-types/05-array-methods/article.md b/1-js/05-data-types/05-array-methods/article.md
index a706499bb..62699a50d 100644
--- a/1-js/05-data-types/05-array-methods/article.md
+++ b/1-js/05-data-types/05-array-methods/article.md
@@ -1,6 +1,10 @@
# ØªÙØ§Ø¨Ø¹ اÙÙ
صÙÙÙØ§Øª (Array methods)
+<<<<<<< HEAD
ØªÙØ¯ÙÙ
اÙÙ
صÙÙÙØ§Øª ØªÙØ§Ø¨Ùع Ø¹Ø¯ÙØ¯Ø© ØªÙØ³ÙÙÙÙ Ø§ÙØªØ¹Ø§Ù
Ù Ù
Ø¹ÙØ§. ÙÙØªØ¨Ø³ÙØ·ÙØ§ سÙÙØ³ÙÙ
ÙØ§ Ø¥ÙÙ Ù
جÙ
ÙØ¹Ø§Øª Ø¨ØØ³Ø¨ اÙÙØ¸ÙÙØ© ÙÙ ÙØ°Ø§ اÙÙØµÙ ÙÙØ´Ø±Ø ÙÙ Ù
ÙÙØ§ عÙÙ ØØ¯Ø©.
+=======
+Arrays provide a lot of methods. To make things easier, in this chapter, they are split into groups.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## Ø¥Ø¶Ø§ÙØ© Ø§ÙØ¹Ùاصر ÙØ¥Ø²Ø§ÙØªÙØ§
@@ -32,11 +36,15 @@ alert(arr.length); // 3
Ø£ÙØ²ÙÙ Ø§ÙØ¹Ùصر صØÙØØ ÙÙÙÙÙ Ù
ا زا٠Ù٠اÙÙ
صÙÙÙØ© Ø«ÙØ§Ø«Ø© Ø¹ÙØ§ØµØ±Ø ÙÙ
ا ÙØ±Ù ÙÙ arr.length == 3.
+<<<<<<< HEAD
ÙØ°Ø§ Ø·Ø¨ÙØ¹ÙØ Ø¥Ø° ÙÙØ²ÙÙ delete obj.key اÙÙÙÙ
Ø© بÙ
ÙØªØ§ØÙا key⦠ÙÙØ°Ø§ ÙÙØ·. ÙÙÙØ¹ ÙÙÙØ§Ø¦Ùات ربÙÙ
Ø§Ø ÙÙÙÙØ§ ÙØ±ÙØ¯ÙØ§ ÙÙÙ
صÙÙÙØ§Øª Ø£Ù ØªÙØªÙÙ ÙÙ Ø§ÙØ¹Ùاصر عÙ٠اÙÙÙ
ÙÙ ÙØªØ£Ø®Ø° اÙÙØ±Ø§Øº Ø§ÙØ¬Ø¯Ùد. أ٠أÙÙØ§ ÙØªÙÙØ¹ أ٠تصغر اÙÙ
صÙÙÙØ© Ø§ÙØ¢Ù.
+=======
+That's natural, because `delete obj.key` removes a value by the `key`. It's all it does. Fine for objects. But for arrays we usually want the rest of the elements to shift and occupy the freed place. We expect to have a shorter array now.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ°Ø§ Ø§ÙØ³Ø¨Ø¨ عÙÙÙØ§ استعÙ
Ø§Ù ØªÙØ§Ø¨Ùع Ø®Ø§ØµÙØ© ÙØ°ÙÙ.
-The [arr.splice](mdn:js/Array/splice) method is a swiss army knife for arrays. It can do everything: insert, remove and replace elements.
+The [arr.splice](mdn:js/Array/splice) method is a Swiss army knife for arrays. It can do everything: insert, remove and replace elements.
ÙØ°Ù ØµÙØ§ØºØªÙ:
@@ -62,7 +70,11 @@ alert( arr ); // ["I", "JavaScript"]
Ø±Ø£ÙØªØ سÙÙØ©. ÙØ¨Ø¯Ø£ Ù
Ù Ø§ÙØ¹Ùصر ذ٠اÙÙÙØ±Ø³ 1 ÙÙÙØ²ÙÙ Ø¹ÙØµØ±Ùا ÙØ§ØØ¯Ùا (1).
+<<<<<<< HEAD
Ø§ÙØ¢ÙØ ÙÙØ²ÙÙ Ø«ÙØ§Ø«Ø© Ø¹ÙØ§ØµØ± ÙÙØ³ØªØ¨Ø¯ÙÙØ§ Ø¨Ø¹ÙØµØ±Ù٠آخرÙÙ:
+=======
+In the next example, we remove 3 elements and replace them with the other two:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let arr = [*!*"I", "study", "JavaScript",*/!* "right", "now"];
@@ -84,7 +96,11 @@ let removed = arr.splice(0, 2);
alert( removed ); // "I", "study" <-- ÙØ§Ø¦Ù
Ø© Ø¨Ø§ÙØ¹Ùاصر اÙÙ
ÙØ²Ø§ÙØ©
```
+<<<<<<< HEAD
ÙÙ
Ù٠أ٠ÙÙØ¯Ø±Ø¬ ØªØ§Ø¨ÙØ¹ splice Ø§ÙØ¹Ùاصر دÙÙ Ø¥Ø²Ø§ÙØ© Ø£ÙÙ Ø´ÙØ¡ Ø£ÙØ¶Ùا. ÙÙÙØ ÙØ¶Ø¹ deleteCount ÙØ³Ø§ÙÙ Ø§ÙØµÙر 0:
+=======
+The `splice` method is also able to insert the elements without any removals. For that, we need to set `deleteCount` to `0`:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let arr = ["I", "study", "JavaScript"];
@@ -115,7 +131,11 @@ alert( arr ); // 1,2,3,4,5
### اÙÙØ·Ø¹ slice
+<<<<<<< HEAD
Ø§ÙØªØ§Ø¨Ùع arr.slice أبسط Ø¨ÙØ«Ùر Ù
٠شبÙÙÙ arr.splice.
+=======
+The method [arr.slice](mdn:js/Array/slice) is much simpler than the similar-looking `arr.splice`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ØµÙØ§ØºØªÙ ÙÙ:
@@ -125,7 +145,11 @@ arr.slice([start], [end]);
ÙÙÙ ÙÙØ¹Ùد Ù
صÙÙÙØ© Ø¬Ø¯ÙØ¯Ø©Ù Ø¨ÙØ³Ø® Ø§ÙØ¹Ùاصر Ù
٠اÙÙÙØ±Ø³ `start` Ø¥ÙÙ `end` (Ø¨Ø§Ø³ØªØ«ÙØ§Ø¡ `end`). ÙÙ
Ù٠أ٠تÙÙÙ `start` ÙØØªÙÙ `end` Ø³Ø§ÙØ¨ØªØ§ÙØ Ø¨ÙØ°Ø§ ÙÙØ¹Ø¯Ù اÙÙ
ØØ±Ù٠اÙÙÙÙ
تا٠أÙ
اÙÙ Ø¨Ø¯Ø¡ÙØ§ Ù
Ù ÙÙØ§ÙØ© اÙÙ
صÙÙÙØ©.
+<<<<<<< HEAD
ÙØ°Ø§ Ø§ÙØªØ§Ø¨Ùع ÙØ´Ø¨Ù ØªØ§Ø¨ÙØ¹ Ø§ÙØ³Ùاس٠اÙÙØµÙØ© `str.slice`Ø ÙÙÙÙ Ø¨Ø¯Ù Ø§ÙØ³Ùاس٠اÙÙØµÙØ© اÙÙØ±Ø¹ÙØ©Ø ÙÙØ¹Ùد اÙÙ
صÙÙÙØ§Øª اÙÙØ±Ø¹ÙØ©. Ø¥ÙÙ٠اÙÙ
Ø«Ø§Ù Ø§ÙØ¢ØªÙ:
+=======
+It's similar to a string method `str.slice`, but instead of substrings, it makes subarrays.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
For instance:
@@ -202,7 +226,11 @@ alert( arr.concat(arrayLike) ); // 1,2,something,else
```js
arr.forEach(function(item, index, array) {
+<<<<<<< HEAD
// ... استعÙ
ÙÙÙ
ا ÙÙÙ
ا ØªØ±ÙØ¯
+=======
+ // ... do something with an item
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
});
```
@@ -231,11 +259,22 @@ arr.forEach(function(item, index, array) {
ÙÙØªÙØ§Ø¨ÙØ¹ arr.indexOf Ù arr.lastIndexOf Ù arr.includes ÙÙØ³ Ø§ÙØµÙاغة ÙÙØ¸ÙÙØªÙا Ù٠ذات ÙØ¸ÙÙØ© تÙÙ Ø¨ÙØ³Ø®Ø© اÙÙØµÙص اÙÙØµÙØ©Ø Ø§ÙÙØ±Ù Ø£ÙÙØ§ ÙÙØ§ تتعاÙ
Ù Ù
ع Ø§ÙØ¹Ùاصر بد٠اÙÙ
ØØ§Ø±Ù:
+<<<<<<< HEAD
- `arr.indexOf(item, from)` -- ÙØ¨ØØ« Ø¹Ù Ø§ÙØ¹Ùصر item Ø¨Ø¯Ø¡ÙØ§ Ù
٠اÙÙÙØ±Ø³ fromØ ÙÙÙØ¹Ùد ÙÙØ±Ø³Ù ØÙØ« ÙØ¬Ø¯Ù. ÙÙÙ ÙÙ
ÙØ¬Ø¯ÙØ ÙÙØ¹Ùد -1.
- `arr.lastIndexOf(item, from)` -- ÙÙØ³ÙØ ÙÙÙÙ Ø§ÙØ¨ØØ« ÙØ¨Ø¯Ø£ Ù
٠اÙÙÙ
ÙÙ ÙÙÙØªÙÙ Ù٠اÙÙØ³Ø§Ø±..
- `arr.includes(item, from)` -- ÙØ¨ØØ« Ø¹Ù Ø§ÙØ¹Ùصر item Ø¨Ø¯Ø¡ÙØ§ Ù
٠اÙÙÙØ±Ø³ fromØ ÙÙÙØ¹Ùد true Ø¥Ù ÙØ¬Ø¯ØªÙ.
Ù
ثاÙ:
+=======
+The methods [arr.indexOf](mdn:js/Array/indexOf) and [arr.includes](mdn:js/Array/includes) have the similar syntax and do essentially the same as their string counterparts, but operate on items instead of characters:
+
+- `arr.indexOf(item, from)` -- looks for `item` starting from index `from`, and returns the index where it was found, otherwise `-1`.
+- `arr.includes(item, from)` -- looks for `item` starting from index `from`, returns `true` if found.
+
+Usually, these methods are used with only one argument: the `item` to search. By default, the search is from the beginning.
+
+For instance:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let arr = [1, 0, false];
@@ -247,6 +286,7 @@ alert(arr.indexOf(null)); // -1
alert(arr.includes(1)); // true
```
+<<<<<<< HEAD
ÙØ§ØØ¸ Ø£ÙÙ Ø§ÙØªÙØ§Ø¨ÙØ¹ تستعÙ
٠اÙÙ
ÙØ§Ø²ÙØ© بÙÙ ===. ÙØ°Ø§ ÙÙ ÙÙÙØ§ ÙØ¨ØØ« ع٠falseØ ÙØ³ØªØ¨ØØ« Ù٠ع٠false ÙÙØ³Ùا ÙÙÙØ³ Ø§ÙØµÙر.
Ù٠أردت Ù
Ø¹Ø±ÙØ© ÙÙÙ
ا ÙØ§Ùت ØªØØªÙ٠اÙÙ
صÙÙÙØ© عÙÙ Ø¹ÙØµØ± Ù
عÙÙÙØ ÙÙØ§ ØªØ±ÙØ¯ Ù
Ø¹Ø±ÙØ© ÙÙØ±Ø³ÙØ ÙØ¯Ø§ÙØ© arr.includes Ù
ÙØ§Ø³Ø¨Ø© ÙÙ.
@@ -257,11 +297,41 @@ alert(arr.includes(1)); // true
const arr = [NaN];
alert(arr.indexOf(NaN)); // â«ÙÙØ¹Ùد â-1 (Ø§ÙØµØÙØ ÙÙ 0 Ø¥ÙÙØ§ Ø£Ù٠اÙÙ
ÙØ§Ø²ÙØ© === ÙØ§ تعÙ
Ù Ù
ع NaN)
alert(arr.includes(NaN)); // true (Ø§ÙØ¢Ù صØÙØ)
+=======
+Please note that `indexOf` uses the strict equality `===` for comparison. So, if we look for `false`, it finds exactly `false` and not the zero.
+
+If we want to check if `item` exists in the array and don't need the index, then `arr.includes` is preferred.
+
+The method [arr.lastIndexOf](mdn:js/Array/lastIndexOf) is the same as `indexOf`, but looks for from right to left.
+
+```js run
+let fruits = ['Apple', 'Orange', 'Apple']
+
+alert( fruits.indexOf('Apple') ); // 0 (first Apple)
+alert( fruits.lastIndexOf('Apple') ); // 2 (last Apple)
```
+````smart header="The `includes` method handles `NaN` correctly"
+A minor, but noteworthy feature of `includes` is that it correctly handles `NaN`, unlike `indexOf`:
+
+```js run
+const arr = [NaN];
+alert( arr.indexOf(NaN) ); // -1 (wrong, should be 0)
+alert( arr.includes(NaN) );// true (correct)
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
+```
+That's because `includes` was added to JavaScript much later and uses the more up-to-date comparison algorithm internally.
+````
+
+<<<<<<< HEAD
### Ø§ÙØ¨ØØ« عبر find Ù findIndex
ÙÙÙ٠أÙÙ ÙØ¯ÙÙØ§ Ù
صÙÙÙØ© Ù
٠اÙÙØ§Ø¦ÙØ§ØªØ ÙÙÙ ÙØ¬Ø¯ اÙÙØ§Ø¦Ù ØØ³Ø¨ شرط Ù
عÙÙÙØ
+=======
+### find and findIndex/findLastIndex
+
+Imagine we have an array of objects. How do we find an object with a specific condition?
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ§ ÙÙ
ÙÙÙØ§ Ø§Ø³ØªØºÙØ§Ù Ø§ÙØªØ§Ø¨Ùع arr.find(fn).
@@ -280,7 +350,11 @@ let result = arr.find(function(item, index, array) {
- `index` : اÙÙÙØ±Ø³.
- `array` : اÙÙ
صÙÙÙØ© ÙÙØ³Ùا.
+<<<<<<< HEAD
Ù٠أعادت trueØ ÙØªÙÙÙÙ Ø§ÙØ¨ØØ« ÙÙÙØ¹Ø§Ø¯ Ø§ÙØ¹Ùصر item. Ø¥Ù ÙÙ
ÙÙØ¬Ø¯ Ø´ÙØ¡ ÙÙÙØ¹Ø§Ø¯ undefined.
+=======
+If it returns `true`, the search is stopped, the `item` is returned. If nothing is found, `undefined` is returned.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ±Ù ÙÙ ÙØ°Ø§ اÙÙ
ثا٠Ù
صÙÙÙØ© Ù
٠اÙÙ
ستخدÙ
ÙÙØ ÙÙÙÙ Ù
ستخدÙ
ØÙÙØ§Ù id Ùname. ÙØ±Ùد Ø§ÙØ°Ù ÙØªÙاÙÙ Ù
ع Ø§ÙØ´Ø±Ø· id == 1:
@@ -296,11 +370,38 @@ let user = users.find(item => item.id == 1);
alert(user.name); // John
```
+<<<<<<< HEAD
ÙÙ Ø§ÙØÙØ§Ø© Ø§ÙØ¹Ù
ÙÙØ©Ø ÙÙØ«Ùر استعÙ
ا٠اÙÙØ§Ø¦Ùات Ù٠اÙÙ
صÙÙÙØ§ØªØ ÙÙÙØ°Ø§ ÙØ§ÙØªØ§Ø¨ÙØ¹ find Ù
ÙÙØ¯ Ø¬Ø¯ÙØ§ ÙÙØ§.
+=======
+In real life, arrays of objects are a common thing, so the `find` method is very useful.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
ÙÙÙ Ù
ÙØ§ØØ¸Ø© بأÙÙØ§ Ù٠اÙÙ
ثا٠Ù
Ø±ÙØ±Ùا ÙÙØªØ§Ø¨Ùع find Ø§ÙØ¯Ø§ÙØ© item => item.id == 1 ÙÙÙÙØ§ ÙØ³ÙØ· ÙØ§ØØ¯. ÙØ°Ø§ Ø·Ø¨ÙØ¹Ù ÙÙØ§Ø¯Ø±Ùا Ù
ا ÙØ³ØªØ¹Ù
٠اÙÙÙØ³Ø·Ø§Ø¡ Ø§ÙØ¨ÙÙØ© ÙÙ ÙØ°Ù Ø§ÙØ¯Ø§ÙØ©
+<<<<<<< HEAD
ÙØªØ´Ø§Ø¨Ù Ø§ÙØªØ§Ø¨Ùع [arr.findIndex](mdn:js/Array/findIndex) ÙØ«ÙØ±ÙØ§ Ù
ع ÙØ°Ø§Ø عدا عÙ٠أÙÙÙ ÙÙØ¹Ùد ÙÙØ±Ø³ Ø§ÙØ¹Ùصر Ø§ÙØ°Ù ÙØ¬Ø¯Ù Ø¨Ø¯Ù Ø§ÙØ¹Ùصر ÙÙØ³ÙØ ÙÙÙØ¹Ùد â-1 ÙÙ ÙÙ
ÙØ¬Ø¯ Ø´ÙØ¦Ùا.
+=======
+The [arr.findIndex](mdn:js/Array/findIndex) method has the same syntax but returns the index where the element was found instead of the element itself. The value of `-1` is returned if nothing is found.
+
+The [arr.findLastIndex](mdn:js/Array/findLastIndex) method is like `findIndex`, but searches from right to left, similar to `lastIndexOf`.
+
+Here's an example:
+
+```js run
+let users = [
+ {id: 1, name: "John"},
+ {id: 2, name: "Pete"},
+ {id: 3, name: "Mary"},
+ {id: 4, name: "John"}
+];
+
+// Find the index of the first John
+alert(users.findIndex(user => user.name == 'John')); // 0
+
+// Find the index of the last John
+alert(users.findLastIndex(user => user.name == 'John')); // 3
+```
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
### Ø§ÙØªØ±Ø´ÙØ filter
@@ -380,6 +481,11 @@ alert(arr); // *!*1, 15, 2*/!*
عÙÙ Ø§ÙØ¯Ø§ÙØ© Ù
ÙØ§Ø²ÙØ© ÙÙÙ
تÙÙ Ø§Ø«ÙØªÙÙ (Ø£ÙÙØ§ ÙØ§Ùتا) ÙØ¥Ø¹Ø§Ø¯Ø© اÙÙØ§ØªØ¬:
+<<<<<<< HEAD
+=======
+The function should compare two arbitrary values and return:
+
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
function compare(a, b) {
if (a > b) return 1; // if the first value is greater than the second
@@ -408,11 +514,19 @@ alert(arr); // *!*1, 2, 15*/!*
Ø§ÙØ¢Ù صارت تعÙ
Ù ÙÙ
ا ÙØ±Ùد.
+<<<<<<< HEAD
ÙÙØªÙÙÙ ÙØØ¸Ø© ÙÙÙÙÙØ± ÙÙÙ
ا ÙØØ¯Ø« تÙ
اÙ
ÙØ§. Ø£ÙØªÙÙ٠بأÙ٠اÙÙ
صÙÙÙØ© arr ÙÙ
ÙÙ Ø£Ù ØªØØªÙ٠أÙÙ Ø´ÙØ¡Ø Ø£ÙÙ Ø´ÙØ¡ Ù
Ù Ø§ÙØ£Ø¹Ø¯Ø§Ø¯ Ø£Ù Ø§ÙØ³Ùاس٠اÙÙØµÙØ© أ٠اÙÙØ§Ø¦Ùات Ø£Ù ØºÙØ±Ùا. ÙÙÙ Ù
ا ÙØ¯ÙÙØ§ ÙÙ Ù
جÙ
ÙØ¹Ø© Ù
Ù Ø§ÙØ¹Ùاصر. ÙØªØ±ØªÙØ¨ÙØ§ ÙØØªØ§Ø¬ Ø¯Ø§ÙØ© ØªØ±ØªÙØ¨ ØªØ¹Ø±Ù Ø·Ø±ÙØ© Ù
ÙØ§Ø±ÙØ© Ø¹ÙØ§ØµØ± اÙÙ
صÙÙÙØ©. Ù
بدئÙÙØ§Ø Ø§ÙØªØ±ØªÙب ÙÙÙÙ Ø¨Ø§ÙØ³Ùاس٠اÙÙØµÙØ©.
The `arr.sort(fn)` method implements a generic sorting algorithm. We don't need to care how it internally works (an optimized [quicksort](https://en.wikipedia.org/wiki/Quicksort) or [Timsort](https://en.wikipedia.org/wiki/Timsort) most of the time). It will walk the array, compare its elements using the provided function and reorder them, all we need is to provide the `fn` which does the comparison.
باÙÙ
ÙØ§Ø³Ø¨Ø©Ø Ù٠أردت Ù
Ø¹Ø±ÙØ© Ø§ÙØ¹Ùاصر Ø§ÙØªÙ تÙÙØ§Ø²ÙÙØ§ Ø§ÙØ¯Ø§ÙØ© ØØ§ÙÙÙØ§Ø ÙÙØ§ بأس. ÙÙ ÙÙØªÙÙ Ø£ØØ¯ ÙÙ Ø¹Ø±Ø¶ØªÙØ§:
+=======
+Let's step aside and think about what's happening. The `arr` can be an array of anything, right? It may contain numbers or strings or objects or whatever. We have a set of *some items*. To sort it, we need an *ordering function* that knows how to compare its elements. The default is a string order.
+
+The `arr.sort(fn)` method implements a generic sorting algorithm. We don't need to care how it internally works (an optimized [quicksort](https://en.wikipedia.org/wiki/Quicksort) or [Timsort](https://en.wikipedia.org/wiki/Timsort) most of the time). It will walk the array, compare its elements using the provided function and reorder them, all we need is to provide the `fn` which does the comparison.
+
+By the way, if we ever want to know which elements are compared -- nothing prevents us from alerting them:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
[1, -2, 15, 2, 0, 8].sort(function(a, b) {
@@ -485,7 +599,11 @@ alert(arr); // 5,4,3,2,1
ÙØ°Ø§ Ù
ا ÙÙØ¹ÙÙ Ø§ÙØªØ§Ø¨Ùع [str.split(delim)](mdn:js/String/splitâ. ÙØ£Ø®Ø° Ø§ÙØ³ÙØ³ÙØ© اÙÙØµÙØ© ÙÙÙØ³Ù
ÙØ§ Ø¥ÙÙ Ù
صÙÙÙØ© ØØ³Ø¨ Ù
ØØ±Ù اÙÙØ§Ø³ÙÙ
delim اÙÙ
ÙØ¯ÙÙ
.
+<<<<<<< HEAD
Ù٠اÙÙ
Ø«Ø§Ù Ø£Ø¹ÙØ§Ù ÙÙØ³Ù
ØØ³Ø¨ Â«ÙØ§ØµÙØ© Ø¨Ø¹Ø¯ÙØ§ Ù
Ø³Ø§ÙØ©Â»:
+=======
+In the example below, we split by a comma followed by a space:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let names = "Bilbo, Gandalf, Nazgul";
@@ -551,9 +669,21 @@ let value = arr.reduce(
- `index` -- Ù
ÙØ§Ù Ø§ÙØ¹Ùصر.
- `array` -- اÙÙ
صÙÙÙØ© ÙÙØ³Ù.
+<<<<<<< HEAD
ØÙÙ ØªÙØ·Ø¨ÙÙ Ø§ÙØ¯Ø§ÙØ©Ø ØªÙÙ
Ø±ÙØ± Ø¥ÙÙÙØ§ ÙØªÙجة اÙÙØ¯Ø§Ø¡ Ø§ÙØ³Ø§Ø¨Ù Ù٠أÙÙÙ ÙØ³ÙØ·. Ø£Ø¬ÙØ Ù
عÙÙØ¯ ÙÙÙÙÙØ§Ø ÙÙÙ ÙÙØ³ ÙÙ
ا تتخÙÙÙ ÙÙ ÙÙÙØ§ Ø£Ù٠اÙÙØ³ÙØ· Ø§ÙØ£Ù٠بÙ
ثابة Â«Ø°Ø§ÙØ±Ø©Â» تخزÙ٠اÙÙØªÙجة اÙÙÙØ§Ø¦ÙØ© Ù
٠إجراءات Ø§ÙØªÙÙÙØ° Ø§ÙØªÙ Ø³Ø¨ÙØªÙا. ÙÙ٠آخر ÙØ¯Ø§Ø¡ ØªØµÙØ± ÙØªÙجة Ø§ÙØªØ§Ø¨Ùع reduce.
ربÙÙ
ا ÙÙØ¯ÙÙ
Ù
ثاÙÙØ§ ÙØªØ³ÙÙ٠اÙÙ
Ø³Ø£ÙØ©. ÙÙØ§ ÙØ¹Ø±Ù Ù
جÙ
ÙØ¹Ø© Ø¹ÙØ§ØµØ± اÙÙ
صÙÙÙØ© Ù٠سطر برÙ
Ø¬Ù ÙØ§ØØ¯:
+=======
+As the function is applied, the result of the previous function call is passed to the next one as the first argument.
+
+So, the first argument is essentially the accumulator that stores the combined result of all previous executions. And at the end, it becomes the result of `reduce`.
+
+Sounds complicated?
+
+The easiest way to grasp that is by example.
+
+Here we get a sum of an array in one line:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let arr = [1, 2, 3, 4, 5];
@@ -612,9 +742,15 @@ let arr = [];
arr.reduce((sum, current) => sum + current);
```
+<<<<<<< HEAD
Ø§ÙØ´ÙÙØ±Ø© Ø§ÙØ³Ø§Ø¨ÙØ© ستطÙÙ Ø®Ø·Ø£Ø Ø¥Ø° ÙØ§ ÙÙ
Ù٠استدعاء reduce Ù
ع Ù
صÙÙÙØ© ÙØ§Ø±ØºØ© دÙÙ ÙÙÙ
Ø© Ø£ÙÙÙØ©Ø ÙØªØÙ اÙÙ
Ø´ÙÙØ© بتÙÙÙØ± ÙÙÙ
Ø© Ø£ÙÙÙØ©Ø ÙØ³ØªØ¹Ø§Ø¯ Ø¢ÙØ°Ø§Ù. ÙØ°Ø§ Ø®ÙØ° ÙØ°Ù اÙÙØµÙØØ© ÙØØ¯ÙØ¯ ÙÙÙ
Ø© Ø£ÙÙÙØ© دÙÙ
ÙØ§.
ÙØ§ ÙØ®ØªÙÙ Ø§ÙØªØ§Ø¨Ùع [arr.reduceRight](mdn:js/Array/reduceRight)Ø¹Ù ÙØ°Ø§ Ø£Ø¹ÙØ§Ù Ø¥ÙØ§ بأÙÙÙ ÙØ¨Ø¯Ø£ Ù
٠اÙÙÙ
ÙÙ ÙÙÙØªÙ٠عÙ٠اÙÙØ³Ø§Ø±.
+=======
+So it's advised to always specify the initial value.
+
+The method [arr.reduceRight](mdn:js/Array/reduceRight) does the same but goes from right to left.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## Array.isArray
@@ -622,7 +758,7 @@ arr.reduce((sum, current) => sum + current);
```js run
alert(typeof {}); // object
-alert(typeof []); // same
+alert(typeof []); // object (same)
```
â¦ÙÙÙÙØ اÙÙ
صÙÙÙØ§Øª تستعÙ
Ù ÙØ«ÙØ±ÙØ§ Ø¬Ø¯ÙØ§ ÙØ¯Ø±Ø¬Ø© ØªÙØ¯ÙÙ
ØªØ§Ø¨ÙØ¹ خاص ÙÙØ°Ø§ Ø§ÙØºØ±Ø¶: Array.isArray(value)â. ÙÙØ¹Ùد ÙØ°Ø§ Ø§ÙØªØ§Ø¨Ùع true ÙÙ ÙØ§Ùت value Ù
صÙÙÙØ© ØÙÙØ§Ø Ùfalse ÙÙ ÙÙ
تÙÙ.
@@ -637,7 +773,11 @@ alert(Array.isArray([])); // true
ØªÙØ¨Ù Ø£ØºÙØ¨ ØªÙØ§Ø¨Ùع اÙÙ
صÙÙÙØ§Øª ØªÙØ±ÙØ¨ÙØ§Ø Ø§ÙØªÙابع Ø§ÙØªÙ ØªØ³ØªØ¯Ø¹Ù Ø¯ÙØ§ÙÙØ§ (Ù
ث٠find Ùfilter ÙmapØ Ø¹Ø¯Ø§ sort) - ØªÙØ¨Ù اÙÙ
ÙØ¹Ø§Ù
Ù Ø§ÙØ§Ø®ØªÙار٠thisArg.
+<<<<<<< HEAD
ÙÙ
ÙØ´Ø±Ø ÙØ°Ø§ اÙÙ
ÙØ¹Ø§Ù
Ù ÙÙ Ø§ÙØ£ÙساÙ
Ø£Ø¹ÙØ§Ù إذ Ø£ÙÙÙ ÙØ§Ø¯Ø±Ùا Ù
ا ÙÙØ³ØªØ¹Ù
Ù. ÙÙÙ٠عÙÙÙØ§ Ø§ÙØØ¯ÙØ« عÙÙ ÙØ£Ùا ÙÙÙÙ Ø§ÙØ´Ø±Ø ÙØ§ÙØµÙØ§.
+=======
+That parameter is not explained in the sections above, because it's rarely used. But for completeness, we have to cover it.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ°Ù Ø§ÙØµÙاغة اÙÙØ§Ù
ÙØ© ÙÙØ°Ù Ø§ÙØªÙØ§Ø¨ÙØ¹:
@@ -704,7 +844,15 @@ A call to `users.filter(army.canJoin, army)` can be replaced with `users.filter(
- `slice(start, end)` -- creates a new array, copies elements from index `start` till `end` (not inclusive) into it.
- `concat(...items)` -- returns a new array: copies all members of the current one and adds `items` to it. If any of `items` is an array, then its elements are taken.
+<<<<<<< HEAD
* ÙÙÙ
Ø±ÙØ± عÙÙ Ø¹ÙØ§ØµØ± اÙÙ
صÙÙÙØ©:
+=======
+- To search among elements:
+ - `indexOf/lastIndexOf(item, pos)` -- look for `item` starting from position `pos`, and return the index or `-1` if not found.
+ - `includes(value)` -- returns `true` if the array has `value`, otherwise `false`.
+ - `find/filter(func)` -- filter elements through the function, return first/all values that make it return `true`.
+ - `findIndex` is like `find`, but returns the index instead of a value.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
- `forEach(func)` -- ÙØ³ØªØ¯Ø¹Ù `func` ÙÙÙÙ Ø¹ÙØµØ± ÙÙØ§ ÙÙØ¹Ùد Ø£ÙÙ Ø´ÙØ¡.
@@ -715,11 +863,16 @@ A call to `users.filter(army.canJoin, army)` can be replaced with `users.filter(
- `split/join` -- convert a string to array and back.
- `reduce/reduceRight(func, initial)` -- calculate a single value over the array by calling `func` for each element and passing an intermediate result between the calls.
+<<<<<<< HEAD
- `map(func)` -- Ø£ÙØ´Ùئ Ù
صÙÙÙØ© Ø¬Ø¯ÙØ¯Ø© Ù
Ù ÙØªØ§Ø¦Ø¬ استدعاء func ÙÙÙÙ Ù
Ù Ø¹ÙØ§ØµØ± اÙÙ
صÙÙÙØ©.
- `sort(func)` -- Ø§ÙØ±Ø² اÙÙ
صÙÙÙØ© ÙÙ
ا ÙÙ ÙØ£Ø¹Ùد ÙØ§ØªØ¬ اÙÙØ±Ø².
- `reverse()` -- Ø§Ø¹ÙØ³ Ø¹ÙØ§ØµØ± اÙÙ
صÙÙÙØ© ÙÙ
ا ÙÙ ÙØ£Ø¹Ùد ÙØ§ØªØ¬ Ø§ÙØ¹Ùس.
- `split/join` -- ØÙÙ٠اÙÙ
صÙÙÙØ© Ø¥ÙÙ Ø³ÙØ³ÙØ© ÙØµÙØ©Ø ÙØ§ÙØ¹ÙØ³ Ø£ÙØ¶Ùا.
- `reduce(func, initial)`-- Ø§ØØ³Ø¨ ÙÙÙ
Ø© Ù
٠اÙÙ
صÙÙÙØ© باستدعاء func عÙÙ ÙÙÙ Ø¹ÙØµØ± ÙÙÙØ§ ÙØªÙ
Ø±ÙØ± اÙÙØ§ØªØ¬ بÙÙ ÙÙ٠استدعاء ÙØ¢Ø®Ø±.
+=======
+- Additionally:
+ - `Array.isArray(value)` checks `value` for being an array, if so returns `true`, otherwise `false`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
* Additionally:
- `Array.isArray(arr)` â ÙÙØØµ ÙÙ ÙØ§Ùت `arr` Ù
صÙÙÙØ© Ø£Ù
ÙØ§.
@@ -734,6 +887,7 @@ A call to `users.filter(army.canJoin, army)` can be replaced with `users.filter(
These methods behave sort of like `||` and `&&` operators: if `fn` returns a truthy value, `arr.some()` immediately returns `true` and stops iterating over the rest of items; if `fn` returns a falsy value, `arr.every()` immediately returns `false` and stops iterating over the rest of items as well.
We can use `every` to compare arrays:
+
```js run
function arraysEqual(arr1, arr2) {
return arr1.length === arr2.length && arr1.every((value, index) => value === arr2[index]);
@@ -750,7 +904,11 @@ A call to `users.filter(army.canJoin, army)` can be replaced with `users.filter(
For the full list, see the [manual](mdn:js/Array).
+<<<<<<< HEAD
ÙØ¯ ÙØ¨Ø¯Ù Ù
٠اÙÙØ¸Ø±Ø© Ø§ÙØ£ÙÙ٠أ٠ÙÙØ§Ù Ø§ÙØ¹Ø¯Ùد Ù
Ù Ø§ÙØ·Ø±Ù Ø ÙØµØ¹Ø¨ ØªØ°ÙØ±Ùا. ÙÙÙÙ Ù٠اÙÙØ§Ùع ÙØ°Ø§ أسÙÙ Ø¨ÙØ«Ùر.
+=======
+At first sight, it may seem that there are so many methods, quite difficult to remember. But actually, that's much easier.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø§ÙØ¸Ø± Ù
Ù Ø®ÙØ§Ù ÙØ±ÙØ© Ø§ÙØºØ´ ÙÙØ· ÙØªÙÙ٠عÙÙ Ø¯Ø±Ø§ÙØ© Ø¨ÙØ§. Ø«Ù
ØÙ Ù
ÙØ§Ù
ÙØ°Ø§ اÙÙØµÙ ÙÙÙ
Ù
ارسة Ø Ø¨ØÙØ« ÙÙÙÙ ÙØ¯Ù٠خبرة Ù٠أساÙÙØ¨ Ø§ÙØµÙÙÙ.
diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md
index c27c0f771..640a6bbda 100644
--- a/1-js/05-data-types/06-iterable/article.md
+++ b/1-js/05-data-types/06-iterable/article.md
@@ -33,7 +33,7 @@ To make the `range` object iterable (and thus let `for..of` work) we need to add
1. When `for..of` starts, it calls that method once (or errors if not found). The method must return an *iterator* -- an object with the method `next`.
2. Onward, `for..of` works *only with that returned object*.
3. When `for..of` wants the next value, it calls `next()` on that object.
-4. The result of `next()` must have the form `{done: Boolean, value: any}`, where `done=true` means that the iteration is finished, otherwise `value` is the next value.
+4. The result of `next()` must have the form `{done: Boolean, value: any}`, where `done=true` means that the loop is finished, otherwise `value` is the next value.
Here's the full implementation for `range` with remarks:
@@ -43,10 +43,18 @@ let range = {
to: 5,
};
+<<<<<<< HEAD
// 1. Ø¹ÙØ¯ تشغÙÙ Ø§ÙØªÙرار for..of ÙÙ٠تÙÙÙ
باستدعائ ÙØ°Ù Ø§ÙØ¯Ø§ÙØ©
range[Symbol.iterator] = function () {
// ... ÙÙØ°Ù Ø§ÙØ¯Ø§ÙØ© تÙÙÙ
بإرجاع اÙÙØ§Ø¦Ù اÙÙ
ØªÙØ±Ø±:
// 2. بعد ذÙÙØ ÙØ¹Ù
Ù Ø§ÙØªÙرار for..of عÙÙ ÙØ°Ø§ اÙÙ
ØªÙØ±Ø± ÙÙØ· Ø¨Ø§ØØ«Ùا ع٠اÙÙÙÙ
Ø§ÙØªØ§ÙÙØ©
+=======
+// 1. call to for..of initially calls this
+range[Symbol.iterator] = function() {
+
+ // ...it returns the iterator object:
+ // 2. Onward, for..of works only with the iterator object below, asking it for next values
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
return {
current: this.from,
last: this.to,
@@ -182,7 +190,11 @@ When we use JavaScript for practical tasks in a browser or any other environment
عÙ٠سبÙ٠اÙÙ
Ø«Ø§ÙØ ستجد أ٠اÙÙØµÙص (strings) عبارة ع٠Ù
ØªÙØ±Ø± (ØÙØ« ÙÙ
Ù٠استخداÙ
`for..of` Ù
Ø¹ÙØ§) ÙÙØ°ÙÙ Ù٠شبÙÙØ© باÙÙ
صÙÙÙÙ (ÙØ£ÙÙØ§ ØªØØªÙ٠عÙÙ `length` Ù `indexes`).
+<<<<<<< HEAD
ÙÙÙ٠اÙÙ
ØªÙØ±Ø± ÙÙ
ÙÙ Ø£Ù ÙØ§ ÙÙÙ٠شبÙÙÙØ§ باÙÙ
صÙÙÙÙ. ÙØ§ÙØ¹ÙØ³ صØÙØ.
+=======
+But an iterable may not be array-like. And vice versa an array-like may not be iterable.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
عÙ٠سبÙ٠اÙÙ
Ø«Ø§ÙØ ÙØ¥Ù اÙÙØ§Ø¦Ù `range` Ø§ÙØ°Ù استخدÙ
ÙØ§Ù سابÙÙØ§ ÙÙ Ù
ØªÙØ±Ø± Ø ÙÙÙÙÙ ÙÙØ³ شبÙÙÙØ§ باÙÙ
صÙÙÙÙ ÙØ£ÙÙØ§ ÙØ§ ØªØØªÙ٠عÙÙ `indexes` Ø£Ù `length`.
@@ -226,8 +238,13 @@ alert(arr.pop()); // World
ÙÙØ°Ø§ Ù
Ø§ÙØØ¯Ø« Ø£ÙØ¶Ø§ ÙÙÙ
ØªÙØ±Ø±:
+<<<<<<< HEAD
```js
// عÙÙ ÙØ±Ø¶ أ٠اÙÙØ§Ø¦Ù range Ù
Ø£Ø®ÙØ° Ù
٠اÙÙ
Ø«Ø§Ù Ø§ÙØ³Ø§Ø¨Ù
+=======
+```js run
+// assuming that range is taken from the example above
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
let arr = Array.from(range);
alert(arr); // 1,2,3,4,5 (ÙØØ¯Ø« Ø§ÙØªØÙÙÙ Ù
Ù Ù
صÙÙÙØ© Ø¥ÙÙ ÙØµ باستخداÙ
toString)
```
@@ -242,8 +259,13 @@ Array.from(obj[, mapFn, thisArg])
عÙ٠سبÙ٠اÙÙ
ثاÙ:
+<<<<<<< HEAD
```js
// عÙÙ ÙØ±Ø¶ أ٠اÙÙØ§Ø¦Ù range Ù
Ø£Ø®ÙØ° Ù
٠اÙÙ
Ø«Ø§Ù Ø§ÙØ³Ø§Ø¨Ù
+=======
+```js run
+// assuming that range is taken from the example above
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
// ØªØ±Ø¨ÙØ¹ Ù٠رÙÙ
let arr = Array.from(range, (num) => num * num);
@@ -279,7 +301,11 @@ for (let char of str) {
alert(chars);
```
+<<<<<<< HEAD
...ÙÙÙÙ ÙØ°Ø§ Ø£ÙØµØ±.
+=======
+...But it is shorter.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ØØªÙ Ø£ÙÙ ÙÙ
ÙÙÙØ§ Ø£Ù ÙØ¨ÙÙ Ø¯Ø§ÙØ© `slice` Ù
ØªÙØ§ÙÙØ© Ù
ع Ø§ÙØ£Ø´ÙØ§Ù Ø£ÙØ¶Ùا:
diff --git a/1-js/05-data-types/07-map-set/article.md b/1-js/05-data-types/07-map-set/article.md
index a588ff4a2..3412360de 100644
--- a/1-js/05-data-types/07-map-set/article.md
+++ b/1-js/05-data-types/07-map-set/article.md
@@ -9,10 +9,15 @@ Till now, we've learned about the following complex data structures:
## Ø§ÙØ®Ø§Ø±Ø·Ø© `Map`
+<<<<<<< HEAD
ØªÙØ¹Ø¯Ù [Ø§ÙØ®Ø§Ø±Ø·Ø©](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) تجÙ
ÙØ¹Ø© ذات Ù
ÙØ§ØªÙØ Ù
Ù Ø¹ÙØ§ØµØ± Ø§ÙØ¨ÙØ§ÙØ§ØªØ تÙ
اÙ
ÙØ§ Ù
ث٠اÙÙØ§Ø¦Ùات `Object`Ø Ù
ع ÙØ±Ù Ø¨Ø³ÙØ·Ø Ù٠أÙÙ Ø§ÙØ®Ø§Ø±Ø·Ø© `Map` ØªØªÙØ استعÙ
ا٠اÙÙ
ÙØ§ØªÙØ Ù
ÙÙ
ÙØ§ ÙØ§Ù ÙÙØ¹Ùا.
+=======
+[Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) is a collection of keyed data items, just like an `Object`. But the main difference is that `Map` allows keys of any type.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ°Ù ØªÙØ§Ø¨ÙØ¹ÙØ§ ÙØ®Ø§ØµÙØ§ØªÙØ§:
+<<<<<<< HEAD
- `new Map()â` -- ÙÙÙØ´Ùئ خارطة.
- `map.set(key, value)â` -- ÙØ¶Ø¨Ø· اÙÙÙÙ
Ø© ØØ³Ø¨ Ù
ÙØªØ§ØÙا.
- `map.get(key)â` -- ÙØ¬Ùب اÙÙÙÙ
Ø© ØØ³Ø¨ Ù
ÙØªØ§ØÙØ§Ø Ù`undefined` ÙÙ ÙÙ
ÙÙØ¬Ø¯ `key` ÙÙ Ø§ÙØ®Ø§Ø±Ø·Ø©.
@@ -20,6 +25,15 @@ Till now, we've learned about the following complex data structures:
- `map.delete(key)â` -- ÙÙØ²Ù٠اÙÙÙÙ
Ø© ØØ³Ø¨ Ù
ÙØªØ§ØÙا.
- `map.clear()â` -- ÙÙØ²ÙÙ ÙÙ Ø´ÙØ¡ Ù
Ù Ø§ÙØ®Ø§Ø±Ø·Ø©.
- `map.size` -- ÙÙØ¹Ùد عدد Ø§ÙØ¹Ùاصر Ø§ÙØØ§ÙÙ.
+=======
+- [`new Map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/Map) -- creates the map.
+- [`map.set(key, value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set) -- stores the value by the key.
+- [`map.get(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get) -- returns the value by the key, `undefined` if `key` doesn't exist in map.
+- [`map.has(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has) -- returns `true` if the `key` exists, `false` otherwise.
+- [`map.delete(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete) -- removes the element (the key/value pair) by the key.
+- [`map.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear) -- removes everything from the map.
+- [`map.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size) -- returns the current element count.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¥ÙÙ٠اÙÙ
Ø«Ø§Ù Ø§ÙØ¢ØªÙ:
@@ -101,16 +115,26 @@ map.set('1', 'str1')
```
+<<<<<<< HEAD
## اÙÙ
Ø±ÙØ± عÙ٠خارطة
ÙÙØ§Ù Ø«ÙØ§Ø« طرائ٠ÙÙÙ
Ø±ÙØ± عÙÙ Ø¹ÙØ§ØµØ± `Map` ÙØªØ·Ø¨Ù٠عÙ
ÙÙØ© عÙÙÙØ§:
- `map.keys()â` -- ÙÙØ¹Ùد Ù
ÙØªØ¹Ø¯ÙÙØ¯Ùا ÙÙÙ
ÙØ§ØªÙØØ
- `map.values()â` -- ÙÙØ¹Ùد Ù
ÙØªØ¹Ø¯ÙÙØ¯Ùا ÙÙÙÙÙ
Ø
- `map.entries()â` -- ÙÙØ¹Ùد Ù
ÙØªØ¹Ø¯ÙÙØ¯Ùا ÙÙÙ
Ø¯Ø®ÙØ§Øª `[key, value]`Ø ÙÙÙ Ø§ÙØªÙ تستعÙ
ÙÙØ§ `for..of` Ù
بدئÙÙØ§.
+=======
+## Iteration over Map
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù
ثاÙ:
+<<<<<<< HEAD
```
+=======
+- [`map.keys()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys) -- returns an iterable for keys,
+- [`map.values()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values) -- returns an iterable for values,
+- [`map.entries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries) -- returns an iterable for entries `[key, value]`, it's used by default in `for..of`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
let recipeMap = new Map([
['cucumber', 500],
@@ -166,7 +190,11 @@ alert( map.get('1') ); // str1
```
+<<<<<<< HEAD
ÙÙ ÙØ§Ù Ø£Ù
اÙ
ÙØ§ ÙØ§Ø¦ÙÙØ§ عادÙÙØ§ ÙÙØ±Ùد ØµÙØ§Ø¹Ø© `Map` Ù
ÙÙØ ÙÙÙ
ÙÙÙØ§ استعÙ
Ø§Ù Ø§ÙØªØ§Ø¨Ùع اÙÙ
ضÙ
ÙÙ Ù٠اÙÙØºØ© [Object.entries(obj)](https://wiki.hsoub.com/JavaScript/Object/entries) إذ ÙÙØ¹Ùد Ù
صÙÙÙØ© Ù
ÙÙÙÙØ© Ù
Ù Ø£Ø²ÙØ§Ø¬ âÙ
ÙØ§ØªÙØ/ÙÙÙ
â ÙÙÙØ§Ø¦ÙØ Ø¨ÙÙØ³ Ø§ÙØµÙغة Ø§ÙØªÙ ÙØ·ÙØ¨ÙØ§ Ø°Ø§Ù Ø§ÙØªØ§Ø¨Ùع.
+=======
+If we have a plain object, and we'd like to create a `Map` from it, then we can use built-in method [Object.entries(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries) that returns an array of key/value pairs for an object exactly in that format.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙÙØ°Ø§ ÙÙ
ÙÙ Ø£Ù ÙØµÙع خارطة Ù
Ù ÙØ§Ø¦Ù Ø¨ÙØ°Ù Ø§ÙØ·Ø±ÙÙØ©:
@@ -232,10 +260,23 @@ let obj = Object.fromEntries(map); // Ø¨â«Ø¯ÙÙ â.entries()â
```
+<<<<<<< HEAD
اÙÙØªÙجة ÙÙØ³Ùا إذ Ø£ÙÙ Ø§ÙØªØ§Ø¨Ùع `Object.fromEntries` ÙØªÙÙÙØ¹ ÙØ§Ø¦ÙÙØ§ Ù
ÙØªØ¹Ø¯ÙÙØ¯Ùا ÙØ³ÙØ·ÙØ§ ÙÙØ ÙÙÙØ³ Ù
صÙÙÙØ© Ø¨Ø§ÙØ¶Ø±Ùرة. ÙÙ
ا ÙØ§Ùتعداد اÙÙÙØ§Ø³Ù ÙÙØ®Ø§Ø±Ø·Ø© ÙØªÙÙÙØ¹ ذات Ø£Ø²ÙØ§Ø¬ âÙ
ÙØ§ØªÙØ/ÙÙÙ
â Ø§ÙØªÙ ÙØªÙÙÙØ¹Ùا `map.entries()â`Ø ÙÙÙØ°Ø§ ÙØ¬Ø¯ ÙÙ ÙØ¯Ùا ÙØ§Ø¦ÙÙØ§ عادÙÙØ§ ÙÙ ÙÙØ³ âÙ
ÙØ§ØªÙØ/ÙÙÙ
â Ø§Ùخارطة `map`.
+=======
+A [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) is a special type collection - "set of values" (without keys), where each value may occur only once.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## Ø§ÙØ·ÙÙ
`Set`
+<<<<<<< HEAD
+=======
+- [`new Set([iterable])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/Set) -- creates the set, and if an `iterable` object is provided (usually an array), copies values from it into the set.
+- [`set.add(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add) -- adds a value, returns the set itself.
+- [`set.delete(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete) -- removes the value, returns `true` if `value` existed at the moment of the call, otherwise `false`.
+- [`set.has(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has) -- returns `true` if the value exists in the set, otherwise `false`.
+- [`set.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear) -- removes everything from the set.
+- [`set.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size) -- is the elements count.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø§ÙØ£Ø·ÙÙ
(`Set`) ÙÙ ÙÙØ¹ خاص٠Ù
Ù Ø§ÙØªØ¬Ù
ÙØ¹Ø§Øª ÙÙØ³ ÙÙ Ù
ÙØ§ØªÙØ ÙÙØ§ ÙÙ
ÙÙ Ø£Ù ÙØÙÙ Ø£ÙØ«Ø± Ù
Ù ÙÙÙ
Ø© Ù
ØªØ·Ø§Ø¨ÙØ©. ÙÙ
Ù٠عدÙÙØ§ ÙØ£Ø·ÙÙ
اÙÙ
جÙÙØ±Ø§Øª ÙØ§ÙØ£Ø³ÙØ§ÙØ ØÙØ« ÙØ§ ØªØªÙØ±Ùر Ø£Ù ÙØ·Ø¹Ø© Ù
رتÙÙ.
@@ -278,7 +319,11 @@ alert(user.name); // â«John (Ø«Ù
Ù Pete ÙMary)
```
+<<<<<<< HEAD
ÙÙ
ÙÙ Ø¹ÙØ¶ Ø§ÙØ£Ø·ÙÙ
استعÙ
ا٠Ù
صÙÙÙØ© Ù
٠اÙÙ
ستخدÙ
ÙÙØ Ù
ع ÙØµÙ ÙØªØÙÙÙ Ù
Ù Ø§ÙØ¨ÙØ§ÙØ§Øª Ø¹ÙØ¯ إدخاÙÙØ§ ÙØ£ÙÙØ§ ØªØØ¯Ø« ØªÙØ±Ø§Ø±Ø§Øª (باستعÙ
ا٠[arr.find](https://wiki.hsoub.com/JavaScript/Array/find)). ÙØ°Ø§ Ù
Ù
ÙÙ ÙØ¹Ù
Ø ÙÙÙ Ø§ÙØ£Ø¯Ø§Ø¡ سÙÙÙÙ Ø£Ø´ÙØ¹ Ø¨ÙØ«Ùر ÙØªØ§Ø¨Ùع Ø§ÙØ¨ØØ« `arr.find` ÙÙ
ر٠عÙÙ _ÙØ§Ù
٠اÙÙ
صÙÙÙØ©_ ÙÙÙØØµ ÙÙÙ Ø¹ÙØµØ± ÙÙÙØ§. Ø§ÙØ·ÙÙ
`Set` Ø£ÙØ¶Ù بÙ
راØÙ ÙØ£Ø¯Ø§Ø¤Ù ÙÙ ÙØØµ ØªÙØ±Ùد Ø§ÙØ¹Ùاصر Ù
ÙØØ³ÙÙ٠داخ٠بÙÙØ© اÙÙØºØ©.
+=======
+The alternative to `Set` could be an array of users, and the code to check for duplicates on every insertion using [arr.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find). But the performance would be much worse, because this method walks through the whole array checking every element. `Set` is much better optimized internally for uniqueness checks.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## اÙÙ
Ø±ÙØ± عÙÙ Ø·ÙÙ
@@ -299,16 +344,30 @@ alert(value);
ÙÙÙÙ ÙØ§ØØ¸ ÙÙØ§ Ø·Ø±Ø§ÙØ© Ø§ÙØªØ§Ø¨Ùع: ÙØ¯Ø§ÙØ© رد٠اÙÙØ¯Ø§Ø¡ اÙÙ
ÙÙ
Ø±ÙØ±Ø© Ø¥ÙÙ `forEach` Ø«ÙØ§Ø« ÙÙØ³Ø·Ø§Ø¡: ÙÙÙ
Ø© `value`Ø Ù*ذات اÙÙÙÙ
Ø© Ø§ÙØ£ÙÙÙ* `valueAgain`Ø ÙØ§ÙÙØ§Ø¦Ù اÙÙØ¯Ù. ÙØ§ØØ¸ØªÙ ÙÙÙ ØªÙØ±Ùرت ذات اÙÙÙÙ
Ø© Ù٠اÙÙÙØ³Ø·Ø§Ø¡ Ù
Ø±ÙØªÙÙØ
+<<<<<<< HEAD
ÙØ¹Ø²Ù ÙØ°Ø§ Ø¥ÙÙ ØªÙØ§ÙÙ `Set` Ù
ع `Map` إذ ÙØ¯Ø§ÙØ© Ø±Ø¯Ù Ø§ÙØªØ§Ø¨Ø¹ اÙÙ
ÙÙ
Ø±ÙØ±Ø© Ø¥ÙÙ `forEach` Ø§ÙØ®Ø§Ø±Ø·Ø© Ø«ÙØ§Ø« ÙÙØ³Ø·Ø§Ø¡ Ø£ÙØ¶Ùا. Ù
ع٠ØÙØ Ø£Ù
Ø±ÙØ§ ØºØ±ÙØ¨Ø ÙÙÙÙÙÙØ§ تÙÙØ¯ ÙØªÙسÙÙÙ ØÙØ§ØªÙØ§ ÙÙ Ø£Ø±Ø¯ÙØ§ Ø§Ø³ØªØ¨Ø¯Ø§Ù Ø§ÙØ®Ø§Ø±Ø·Ø© Ø¨Ø§ÙØ·ÙÙ
ÙÙ ØØ§Ùات ØØ±Ø¬Ø©Ø ÙÙ
ا Ø§ÙØ¹Ùس Ø£ÙØ¶Ùا.
+=======
+That's for compatibility with `Map` where the callback passed `forEach` has three arguments. Looks a bit strange, for sure. But this may help to replace `Map` with `Set` in certain cases with ease, and vice versa.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
ا تدعÙ
Ø§ÙØ£Ø·ÙÙ
ÙÙØ³ Ø§ÙØªÙØ§Ø¨ÙØ¹ Ø§ÙØªÙ تدعÙ
ÙØ§ Ø§ÙØ®Ø§Ø±Ø·Ø© ÙÙØªØ¹Ø§Ù
Ù Ù
ع اÙÙ
ÙØªØ¹Ø¯ÙÙØ¯Ø§Øª:
+<<<<<<< HEAD
- `set.keys()â` -- ÙÙØ¹Ùد ÙØ§Ø¦ÙÙØ§ Ù
ÙØªØ¹Ø¯ÙÙØ¯Ùا Ù
٠اÙÙÙÙ
Ø
- `set.values()â` -- تÙ
اÙ
ÙØ§ Ù
ث٠`set.keys()â` (Ù
ÙØ¬Ùد ÙÙØªÙاÙÙ Ù
ع `Map`)Ø
- `set.entries()â` -- ÙÙØ¹Ùد ÙØ§Ø¦ÙÙØ§ Ù
ÙØªØ¹Ø¯ÙÙØ¯Ùا Ù
٠اÙÙ
ÙØ¯Ø®Ùات `[value, value]` (Ù
ÙØ¬Ùد ÙÙØªÙاÙÙ Ù
ع `Map`).
+=======
+- [`set.keys()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/keys) -- returns an iterable object for values,
+- [`set.values()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values) -- same as `set.keys()`, for compatibility with `Map`,
+- [`set.entries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries) -- returns an iterable object for entries `[value, value]`, exists for compatibility with `Map`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## Ù
ÙØ®Øµ
+<<<<<<< HEAD
+=======
+[`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) -- is a collection of keyed values.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø§ÙØ®Ø§Ø±Ø·Ø© `Map` Ù٠تجÙ
ÙØ¹Ø© ذات Ù
ÙØ§ØªÙØ.
@@ -467,27 +526,40 @@ map.set(sorted, word);
```
-- `new Map([iterable])` -- creates the map, with optional `iterable` (e.g. array) of `[key,value]` pairs for initialization.
-- `map.set(key, value)` -- stores the value by the key, returns the map itself.
-- `map.get(key)` -- returns the value by the key, `undefined` if `key` doesn't exist in map.
-- `map.has(key)` -- returns `true` if the `key` exists, `false` otherwise.
-- `map.delete(key)` -- removes the value by the key, returns `true` if `key` existed at the moment of the call, otherwise `false`.
-- `map.clear()` -- removes everything from the map.
-- `map.size` -- returns the current element count.
+- [`new Map([iterable])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/Map) -- creates the map, with optional `iterable` (e.g. array) of `[key,value]` pairs for initialization.
+- [`map.set(key, value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set) -- stores the value by the key, returns the map itself.
+- [`map.get(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get) -- returns the value by the key, `undefined` if `key` doesn't exist in map.
+- [`map.has(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has) -- returns `true` if the `key` exists, `false` otherwise.
+- [`map.delete(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete) -- removes the element by the key, returns `true` if `key` existed at the moment of the call, otherwise `false`.
+- [`map.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear) -- removes everything from the map.
+- [`map.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size) -- returns the current element count.
ÙÙ٠اÙÙÙØ§ÙØ© ÙØ£Ø®Ø° `Array.from(map.values())â` Ù
ØªÙØ¹Ø¯ÙÙØ¯Ø§ ÙÙ
ر٠عÙÙ ÙÙÙ
Ø§ÙØ®Ø§Ø±Ø·Ø© (ÙØ§ ÙØ±Ùد Ù
ÙØ§ØªÙØÙا ÙÙ ÙØ§ØªØ¬ Ø§ÙØ¯Ø§ÙØ©) ÙÙÙØ¹Ùد اÙÙ
صÙÙÙØ© ÙÙØ³Ùا.
ÙÙ
ÙÙÙØ§ (ÙÙ ÙØ°Ù اÙÙ
Ø³Ø£ÙØ©) استعÙ
Ø§Ù ÙØ§Ø¦Ù Ø¹Ø§Ø¯Ù Ø¨Ø¯Ù Ø§ÙØ®Ø§Ø±Ø·Ø©Ø إذ Ø£Ù٠اÙÙ
ÙØ§ØªÙØ Ø³ÙØ§Ø³Ù ÙØµÙØ©. ÙÙØ°Ø§ Ø³ÙØ¨Ø¯Ù Ø§ÙØÙÙ ÙÙ Ø§ØªØ¨Ø¹ÙØ§ ÙØ°Ø§ اÙÙÙØ¬:
+<<<<<<< HEAD
```
+=======
+[`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) -- is a collection of unique values.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
function aclean(arr) {
let obj = {};
+<<<<<<< HEAD
for (let i = 0; i < arr.length; i++) {
let sorted = arr[i].toLowerCase().split("").sort().join("");
obj[sorted] = arr[i];
}
+=======
+- [`new Set([iterable])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/Set) -- creates the set, with optional `iterable` (e.g. array) of values for initialization.
+- [`set.add(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add) -- adds a value (does nothing if `value` exists), returns the set itself.
+- [`set.delete(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete) -- removes the value, returns `true` if `value` existed at the moment of the call, otherwise `false`.
+- [`set.has(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has) -- returns `true` if the value exists in the set, otherwise `false`.
+- [`set.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear) -- removes everything from the set.
+- [`set.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size) -- is the elements count.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
return Object.values(obj);
}
diff --git a/1-js/05-data-types/08-weakmap-weakset/01-recipients-read/solution.md b/1-js/05-data-types/08-weakmap-weakset/01-recipients-read/solution.md
index 6a4c20baf..e2147ccfa 100644
--- a/1-js/05-data-types/08-weakmap-weakset/01-recipients-read/solution.md
+++ b/1-js/05-data-types/08-weakmap-weakset/01-recipients-read/solution.md
@@ -25,7 +25,7 @@ messages.shift();
// now readMessages has 1 element (technically memory may be cleaned later)
```
-The `WeakSet` allows to store a set of messages and easily check for the existance of a message in it.
+The `WeakSet` allows to store a set of messages and easily check for the existence of a message in it.
It cleans up itself automatically. The tradeoff is that we can't iterate over it, can't get "all read messages" from it directly. But we can do it by iterating over all messages and filtering those that are in the set.
diff --git a/1-js/05-data-types/08-weakmap-weakset/article.md b/1-js/05-data-types/08-weakmap-weakset/article.md
index b9336405e..5cb4389b2 100644
--- a/1-js/05-data-types/08-weakmap-weakset/article.md
+++ b/1-js/05-data-types/08-weakmap-weakset/article.md
@@ -1,9 +1,20 @@
+<<<<<<< HEAD

# اÙÙÙØ¹ WeakMap ÙØ§ÙÙÙØ¹ WeakSet: Ø§ÙØ®Ø±Ø§Ø¦Ø· ÙØ§ÙأطÙÙ
ضعÙÙØ© Ø§ÙØ¥Ø´Ø§Ø±Ø©
ÙÙ
ا عرÙÙØ§ Ù
Ù ÙØµÙ «ÙÙØ³ اÙÙ
ÙÙ
ÙØ§ØªÂ»Ø ÙÙ
ÙØØ±ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØ®ÙزÙ٠اÙÙÙÙ
Ø© ÙÙ Ø§ÙØ°Ø§Ùرة طاÙÙ
ا ÙÙ
ÙÙ Ø£Ù ÙØµÙ ÙÙØ§ Ø´ÙØ¡ (Ø£Ù ÙÙ
Ù٠استعÙ
اÙÙØ§ ÙØ§ØÙÙØ§). ÙÙØ°Ø§:
```
+=======
+
+# WeakMap and WeakSet
+
+As we know from the chapter , JavaScript engine keeps a value in memory while it is "reachable" and can potentially be used.
+
+For instance:
+
+```js
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
let john = { name: "John" };
// â«ÙÙ
ÙÙÙØ§ اÙÙØµÙ٠إÙ٠اÙÙØ§Ø¦ÙØ ÙÙ john ÙÙ Ø§ÙØ¥Ø´Ø§Ø±Ø© Ø¥ÙÙÙ
@@ -46,11 +57,17 @@ john = null; // عÙÙØ¶ Ø§ÙØ¥Ø´Ø§Ø±Ø©
// â«ÙÙÙ
ÙÙÙØ§ Ø£Ø®Ø°Ù Ø¨ÙØ°Ù: map.keys()â
```
+<<<<<<< HEAD
عÙÙ Ø§ÙØ¹Ùس ÙØ§Ùخارطة ضعÙÙØ© Ø§ÙØ¥Ø´Ø§Ø±Ø© `WeakMap` Ù
ختÙÙØ© جذرÙÙØ§ Ø¹Ù ÙØ°Ø§Ø ÙÙØ§ تÙ
ÙØ¹ ÙÙØ³ Ù
ÙÙ
ÙØ§Øª Ø£ÙÙÙ Ù
Ù Ù
ÙØ§ØªÙØÙا اÙÙØ§Ø¦Ùات. ÙÙØ£Ø®Ø° بعض Ø§ÙØ£Ù
Ø«ÙØ© ÙØªÙدر٠اÙÙØµØ¯ ÙÙØ§.
+=======
+[`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) is fundamentally different in this aspect. It doesn't prevent garbage-collection of key objects.
+
+Let's see what it means on examples.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## WeakMap
-The first difference between `Map` and `WeakMap` is that keys must be objects, not primitive values:
+The first difference between [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) and [`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) is that keys must be objects, not primitive values:
```
let weakMap = new WeakMap();
@@ -80,10 +97,21 @@ john = null; // عÙÙØ¶ Ø§ÙØ¥Ø´Ø§Ø±Ø©
ÙØ§ تدعÙ
Ø§ÙØ®Ø§Ø±Ø·Ø© ضعÙÙØ© Ø§ÙØ¥Ø´Ø§Ø±Ø© `WeakMap` Ø§ÙØªÙرار (iteration) ÙÙØ§ Ø§ÙØªÙØ§Ø¨ÙØ¹ `keys()â` Ø£Ù `values()â` Ø£Ù `entries()â`Ø ÙÙÙØ°Ø§ ÙØ§ ÙÙØ¯Ø± عÙ٠أخذ ÙÙ٠اÙÙ
ÙØ§ØªÙØ Ø£Ù Ø§ÙÙÙÙ
Ø§ÙØªÙ ÙÙÙØ§. ب٠أÙÙ ÙÙØ®Ø§Ø±Ø·Ø© `WeakMap` Ø§ÙØªÙØ§Ø¨ÙØ¹ Ø§ÙØ¢ØªÙØ©:
+<<<<<<< HEAD
- `weakMap.get(key)â`
- `weakMap.set(key, value)â`
- `weakMap.delete(key)â`
- `weakMap.has(key)â`
+=======
+`WeakMap` has only the following methods:
+
+- [`weakMap.set(key, value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/set)
+- [`weakMap.get(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/get)
+- [`weakMap.delete(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/delete)
+- [`weakMap.has(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/has)
+
+Why such a limitation? That's for technical reasons. If an object has lost all other references (like `john` in the code above), then it is to be garbage-collected automatically. But technically it's not exactly specified *when the cleanup happens*.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
The JavaScript engine decides that. It may choose to perform the memory cleanup immediately or to wait and do the cleaning later when more deletions happen. So, technically, the current element count of a `WeakMap` is not known. The engine may have cleaned it up or not, or did it partially. For that reason, methods that access all keys/values are not supported.
@@ -161,6 +189,7 @@ function process(obj) {
let result = /* ØØ³Ø§Ø¨Ø§Øª اÙÙØ§Ø¦Ù ÙØ°Ø§ */ obj;
cache.set(obj, result);
+ return result;
}
return cache.get(obj);
@@ -198,6 +227,7 @@ function process(obj) {
let result = /* ØØ³Ø§Ø¨Ø§Øª اÙÙØ§Ø¦Ù ÙØ°Ø§ */ obj;
cache.set(obj, result);
+ return result;
}
return cache.get(obj);
@@ -217,11 +247,19 @@ obj = null;
## WeakSet
+<<<<<<< HEAD
ØØªÙÙ Ø§ÙØ£Ø·ÙÙ
ضعÙÙØ© Ø§ÙØ¥Ø´Ø§Ø±Ø© `WeakSet` تسÙ٠ذات Ø§ÙØ³ÙÙÙ:
- ØªØ´Ø¨Ù Ø§ÙØ£Ø·ÙÙ
Ø§ÙØ¹Ø§Ø¯ÙØ© `Set` ÙÙÙÙ ÙØ§ ÙÙ
ÙÙÙØ§ Ø¥ÙÙØ§ Ø¥Ø¶Ø§ÙØ© اÙÙØ§Ø¦Ùات Ø¥ÙÙ `WeakSet` (ÙÙÙØ³ Ø§ÙØ£ÙÙØ§Ø¹ Ø§ÙØ£ÙÙÙØ©).
- ÙØ¨Ù٠اÙÙØ§Ø¦Ù Ù
ÙØ¬ÙØ¯ÙØ§ ÙÙ Ø§ÙØ·ÙÙ
طاÙÙ
ا ÙÙØ§Ù Ù
ا ÙØµÙ Ø¥ÙÙÙ.
- ÙÙØ¯Ø¹Ù
-ÙÙ
ا تدعÙ
`Set`- Ø§ÙØªÙØ§Ø¨ÙØ¹ `add` Ù`has` Ù`delete`Ø ÙÙÙÙ ÙØ§ تدعÙ
`size` Ø£Ù `keys()â` Ø£Ù Ø§ÙØªØ¹Ø¯Ø§Ø¯.
+=======
+[`WeakSet`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet) behaves similarly:
+
+- It is analogous to `Set`, but we may only add objects to `WeakSet` (not primitives).
+- An object exists in the set while it is reachable from somewhere else.
+- Like `Set`, it supports [`add`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Weakset/add), [`has`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Weakset/has) and [`delete`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Weakset/delete), but not `size`, `keys()` and no iterations.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Being "weak", it also serves as additional storage. But not for arbitrary data, rather for "yes/no" facts. A membership in `WeakSet` may mean something about the object.
@@ -255,6 +293,7 @@ The most notable limitation of `WeakMap` and `WeakSet` is the absence of iterati
Ø§ÙØ·ÙÙ
ضعÙÙØ© Ø§ÙØ¥Ø´Ø§Ø±Ø© Ù٠تجÙ
ÙØ¹Ø© ØªØ´Ø¨Ù Ø§ÙØ£Ø·ÙÙ
Ø§ÙØ¹Ø§Ø¯ÙØ©Ø ÙÙØ§ تخزÙÙ Ø¥ÙØ§ اÙÙØ§Ø¦Ùات ÙÙÙØ§Ø ÙÙ
ا ÙØªÙزÙÙÙØ§ Ù
ا Ø¥Ù ØªÙØ¹Ø¯Ù
Ø§ÙØ¥Ø´Ø§Ø±Ø© Ø¥ÙÙÙØ§.
+<<<<<<< HEAD
ÙÙÙØ§ اÙÙÙØ¹Ø§Ù ÙØ§ ÙØ¯Ø¹Ù
Ø§Ù Ø§ÙØªÙØ§Ø¨ÙØ¹ ÙØ§ÙØ®Ø§ØµÙØ§Øª Ø§ÙØªÙ ØªÙØ´Ùر Ø¥ÙÙ Ù٠اÙÙ
ÙØ§ØªÙØ ÙÙÙÙ
Ø§Ø Ø£Ù ØØªÙ Ø¹Ø¯Ø¯ÙØ§. اÙÙ
سÙ
ÙØ ÙÙØ· ÙÙ Ø§ÙØ¹Ù
ÙÙØ§Øª عÙÙ Ø§ÙØ¹Ùاصر ÙÙÙØ§ Ø¹ÙØµØ±Ùا Ø¨Ø¹ÙØµØ±.
ÙÙØ³ØªØ¹Ù
Ù ÙØ°Ø§Ù اÙÙÙØ¹Ø§Ù `WeakMap` Ù`WeakSet` عÙ٠أÙÙÙÙ
ا بÙÙ Ø¨ÙØ§Ùات âØ«Ø§ÙÙÙØ©â Ø¥ÙÙ Ø¬Ø§ÙØ¨ تÙÙ âØ§ÙØ£Ø³Ø§Ø³ÙØ©â ÙØªØ®Ø²ÙÙ Ø§ÙØ¹Ùاصر. ÙÙ Ø£ÙØ²Ù٠اÙÙØ§Ø¦Ù Ù
Ù Ø§ÙØªØ®Ø²ÙÙ Ø§ÙØ£Ø³Ø§Ø³ÙØ ÙÙÙ
ÙÙØ¬Ø¯ Ù٠أ٠إشارة Ø¥ÙØ§ Ù
ÙØªØ§ØÙا ÙÙ `WeakMap` Ø£Ù Ø¹ÙØµØ±Ùا ÙÙ `WeakSet`Ø Ù
سØÙ٠اÙÙ
ØØ±Ù٠تÙÙØ§Ø¦ÙÙØ§.
@@ -358,6 +397,11 @@ let readMap = new WeakMap();
readMap.set(messages[0], new Date(2017, 1, 1));
// Ø³ÙØ±Ù Ø£Ù
ر ÙØ§Ø¦Ù Ø§ÙØªØ§Ø±ÙØ® ÙØ§ØÙÙØ§
```
+=======
+[`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) is `Map`-like collection that allows only objects as keys and removes them together with associated value once they become inaccessible by other means.
+
+[`WeakSet`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet) is `Set`-like collection that stores only objects and removes them once they become inaccessible by other means.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Their main advantages are that they have weak reference to objects, so they can easily be removed by garbage collector.
diff --git a/1-js/05-data-types/09-keys-values-entries/article.md b/1-js/05-data-types/09-keys-values-entries/article.md
index ed4ad83e5..fd38e2aae 100644
--- a/1-js/05-data-types/09-keys-values-entries/article.md
+++ b/1-js/05-data-types/09-keys-values-entries/article.md
@@ -68,7 +68,17 @@ for (let value of Object.values(user)) {
2. استعÙ
Ù ØªÙØ§Ø¨Ùع اÙÙ
صÙÙÙØ§Øª عÙ٠تÙ٠اÙÙ
صÙÙÙØ© (Ù
Ø«ÙÙØ§ map).
3. استعÙ
Ù Object.fromEntries(array)â Ø¹Ù٠اÙÙ
صÙÙÙØ© اÙÙØ§ØªØ¬ ÙØªÙØÙÙÙÙØ§ ثاÙÙØ©Ù Ø¥ÙÙ ÙØ§Ø¦Ù.
+<<<<<<< HEAD
Ø¥ÙÙÙ Ù
ثاÙÙØ§ ÙØ¯ÙÙØ§ ÙØ§Ø¦ÙÙØ§ ÙÙÙ ØªØ³Ø¹ÙØ± Ø§ÙØ¨Ø¶Ø§Ø¦Ø¹Ø ÙÙØ±Ùد Ù
Ø¶Ø§Ø¹ÙØªÙا (إذ Ø§Ø±ØªÙØ¹ Ø§ÙØ¯ÙÙØ§Ø±):
+=======
+If we'd like to apply them, then we can use `Object.entries` followed by `Object.fromEntries`:
+
+1. Use `Object.entries(obj)` to get an array of key/value pairs from `obj`.
+2. Use array methods on that array, e.g. `map`, to transform these key/value pairs.
+3. Use `Object.fromEntries(array)` on the resulting array to turn it back into an object.
+
+For example, we have an object with prices, and would like to double them:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let prices = {
@@ -79,12 +89,22 @@ let prices = {
*!*
let doublePrices = Object.fromEntries(
+<<<<<<< HEAD
// â«ÙØÙÙÙ٠إÙÙ Ù
صÙÙÙØ©Ø Ø«Ù
Ù ÙØ³ØªØ¹Ù
Ù Ø§ÙØ·ÙÙ
Ø Ø«Ù
Ù ÙÙØ¹Ùد Ø¥ÙÙÙØ§ fromEntries اÙÙØ§Ø¦Ù اÙÙ
Ø·ÙÙØ¨
Object.entries(prices).map(([key, value]) => [key, value * 2])
+=======
+ // convert prices to array, map each key/value pair into another pair
+ // and then fromEntries gives back the object
+ Object.entries(prices).map(entry => [entry[0], entry[1] * 2])
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
);
*/!*
alert(doublePrices.meat); // 8
```
+<<<<<<< HEAD
ربÙÙ
ا ØªØ±Ø§Ù ØµØ¹Ø¨ÙØ§ Ø£ÙÙÙ ÙÙÙØ©Ø ÙÙÙÙ ÙØ§ تÙÙÙ ÙØ³ÙØµÙØ± أسÙÙ Ø£ÙØ«Ø± Ù
ت٠Ù
ا بدأت استعÙ
اÙÙØ§ Ù
Ø±ÙØ© ÙØ§Ø«ÙØªØ§Ù ÙØ«Ùاث. ÙÙ
ÙÙ Ø£Ù ÙØµÙع Ø³ÙØ³ÙØ© ÙØ¹ÙØ§ÙØ© Ù
Ù Ø§ÙØªØ¹Ø¯ÙÙØ§Øª Ø¨ÙØ°Ù Ø§ÙØ·Ø±ÙÙØ©:
+=======
+It may look difficult at first sight, but becomes easy to understand after you use it once or twice. We can make powerful chains of transforms this way.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/05-data-types/10-destructuring-assignment/article.md b/1-js/05-data-types/10-destructuring-assignment/article.md
index fb9346aa2..c8693b2c4 100644
--- a/1-js/05-data-types/10-destructuring-assignment/article.md
+++ b/1-js/05-data-types/10-destructuring-assignment/article.md
@@ -2,21 +2,21 @@
The two most used data structures in JavaScript are `Object` and `Array`.
-- Objects allow us to create a single entity that stores data items by key.
+- Objects allow us to create a single entity that stores data items by key.
- Arrays allow us to gather data items into an ordered list.
-Although, when we pass those to a function, it may need not an object/array as a whole. It may need individual pieces.
+However, when we pass these to a function, we may not need all of it. The function might only require certain elements or properties.
-*Destructuring assignment* is a special syntax that allows us to "unpack" arrays or objects into a bunch of variables, as sometimes that's more convenient.
+*Destructuring assignment* is a special syntax that allows us to "unpack" arrays or objects into a bunch of variables, as sometimes that's more convenient.
-Destructuring also works great with complex functions that have a lot of parameters, default values, and so on. Soon we'll see that.
+Destructuring also works well with complex functions that have a lot of parameters, default values, and so on. Soon we'll see that.
## Array destructuring
Here's an example of how an array is destructured into variables:
```js
-// we have an array with the name and surname
+// we have an array with a name and surname
let arr = ["John", "Smith"]
*!*
@@ -40,10 +40,10 @@ alert(firstName); // John
alert(surname); // Smith
```
-As you can see, the syntax is simple. There are several peculiar details though. Let's see more examples, to better understand it.
+As you can see, the syntax is simple. There are several peculiar details though. Let's see more examples to understand it better.
````smart header="\"Destructuring\" does not mean \"destructive\"."
-It's called "destructuring assignment," because it "destructurizes" by copying items into variables. But the array itself is not modified.
+It's called "destructuring assignment," because it "destructurizes" by copying items into variables. However, the array itself is not modified.
It's just a shorter way to write:
```js
@@ -65,7 +65,7 @@ let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic
alert( title ); // Consul
```
-In the code above, the second element of the array is skipped, the third one is assigned to `title`, and the rest of the array items is also skipped (as there are no variables for them).
+In the code above, the second element of the array is skipped, the third one is assigned to `title`, and the rest of the array items are also skipped (as there are no variables for them).
````
````smart header="Works with any iterable on the right-side"
@@ -76,12 +76,12 @@ In the code above, the second element of the array is skipped, the third one is
let [a, b, c] = "abc"; // ["a", "b", "c"]
let [one, two, three] = new Set([1, 2, 3]);
```
-That works, because internally a destructuring assignment works by iterating over the right value. It's kind of syntax sugar for calling `for..of` over the value to the right of `=` and assigning the values.
+That works, because internally a destructuring assignment works by iterating over the right value. It's a kind of syntax sugar for calling `for..of` over the value to the right of `=` and assigning the values.
````
-````smart header="Assign to anything at the left-side"
-We can use any "assignables" at the left side.
+````smart header="Assign to anything on the left-side"
+We can use any "assignables" on the left side.
For instance, an object property:
```js run
@@ -95,9 +95,9 @@ alert(user.surname); // Smith
````
````smart header="Looping with .entries()"
-In the previous chapter we saw the [Object.entries(obj)](mdn:js/Object/entries) method.
+In the previous chapter, we saw the [Object.entries(obj)](mdn:js/Object/entries) method.
-We can use it with destructuring to loop over keys-and-values of an object:
+We can use it with destructuring to loop over the keys-and-values of an object:
```js run
let user = {
@@ -105,7 +105,7 @@ let user = {
age: 30
};
-// loop over keys-and-values
+// loop over the keys-and-values
*!*
for (let [key, value] of Object.entries(user)) {
*/!*
@@ -169,14 +169,14 @@ If we'd like also to gather all that follows -- we can add one more parameter th
let [name1, name2, *!*...rest*/!*] = ["Julius", "Caesar", *!*"Consul", "of the Roman Republic"*/!*];
*!*
-// rest is array of items, starting from the 3rd one
+// rest is an array of items, starting from the 3rd one
alert(rest[0]); // Consul
alert(rest[1]); // of the Roman Republic
alert(rest.length); // 2
*/!*
```
-The value of `rest` is the array of the remaining array elements.
+The value of `rest` is the array of the remaining array elements.
We can use any other variable name in place of `rest`, just make sure it has three dots before it and goes last in the destructuring assignment.
@@ -187,7 +187,7 @@ let [name1, name2, *!*...titles*/!*] = ["Julius", "Caesar", "Consul", "of the Ro
### Default values
-If the array is shorter than the list of variables at the left, there'll be no errors. Absent values are considered undefined:
+If the array is shorter than the list of variables on the left, there will be no errors. Absent values are considered undefined:
```js run
*!*
@@ -234,7 +234,7 @@ The basic syntax is:
let {var1, var2} = {var1:â¦, var2:â¦}
```
-We should have an existing object at the right side, that we want to split into variables. The left side contains an object-like "pattern" for corresponding properties. In the simplest case, that's a list of variable names in `{...}`.
+We should have an existing object on the right side, that we want to split into variables. The left side contains an object-like "pattern" for corresponding properties. In the simplest case, that's a list of variable names in `{...}`.
For instance:
@@ -254,7 +254,7 @@ alert(width); // 100
alert(height); // 200
```
-Properties `options.title`, `options.width` and `options.height` are assigned to the corresponding variables.
+Properties `options.title`, `options.width` and `options.height` are assigned to the corresponding variables.
The order does not matter. This works too:
@@ -418,9 +418,9 @@ alert( title ); // Menu
## Nested destructuring
-If an object or an array contain other nested objects and arrays, we can use more complex left-side patterns to extract deeper portions.
+If an object or an array contains other nested objects and arrays, we can use more complex left-side patterns to extract deeper portions.
-In the code below `options` has another object in the property `size` and an array in the property `items`. The pattern at the left side of the assignment has the same structure to extract values from them:
+In the code below `options` has another object in the property `size` and an array in the property `items`. The pattern on the left side of the assignment has the same structure to extract values from them:
```js run
let options = {
@@ -429,7 +429,7 @@ let options = {
height: 200
},
items: ["Cake", "Donut"],
- extra: true
+ extra: true
};
// destructuring assignment split in multiple lines for clarity
@@ -449,7 +449,7 @@ alert(item1); // Cake
alert(item2); // Donut
```
-All properties of `options` object except `extra` that is absent in the left part, are assigned to corresponding variables:
+All properties of `options` object except `extra` which is absent in the left part, are assigned to corresponding variables:

@@ -459,9 +459,9 @@ Note that there are no variables for `size` and `items`, as we take their conten
## Smart function parameters
-There are times when a function has many parameters, most of which are optional. That's especially true for user interfaces. Imagine a function that creates a menu. It may have a width, a height, a title, items list and so on.
+There are times when a function has many parameters, most of which are optional. That's especially true for user interfaces. Imagine a function that creates a menu. It may have a width, a height, a title, an item list and so on.
-Here's a bad way to write such function:
+Here's a bad way to write such a function:
```js
function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
@@ -469,7 +469,7 @@ function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
}
```
-In real-life, the problem is how to remember the order of arguments. Usually IDEs try to help us, especially if the code is well-documented, but still... Another problem is how to call a function when most parameters are ok by default.
+In real-life, the problem is how to remember the order of arguments. Usually, IDEs try to help us, especially if the code is well-documented, but still... Another problem is how to call a function when most parameters are ok by default.
Like this?
@@ -534,7 +534,7 @@ function({
})
```
-Then, for an object of parameters, there will be a variable `varName` for property `incomingProperty`, with `defaultValue` by default.
+Then, for an object of parameters, there will be a variable `varName` for the property `incomingProperty`, with `defaultValue` by default.
Please note that such destructuring assumes that `showMenu()` does have an argument. If we want all values by default, then we should specify an empty object:
@@ -561,7 +561,7 @@ In the code above, the whole arguments object is `{}` by default, so there's alw
- Destructuring assignment allows for instantly mapping an object or array onto many variables.
- The full object syntax:
```js
- let {prop : varName = default, ...rest} = object
+ let {prop : varName = defaultValue, ...rest} = object
```
This means that property `prop` should go into the variable `varName` and, if no such property exists, then the `default` value should be used.
@@ -571,9 +571,9 @@ In the code above, the whole arguments object is `{}` by default, so there's alw
- The full array syntax:
```js
- let [item1 = default, item2, ...rest] = array
+ let [item1 = defaultValue, item2, ...rest] = array
```
- The first item goes to `item1`; the second goes into `item2`, all the rest makes the array `rest`.
+ The first item goes to `item1`; the second goes into `item2`, and all the rest makes the array `rest`.
- It's possible to extract data from nested arrays/objects, for that the left side must have the same structure as the right one.
diff --git a/1-js/05-data-types/11-date/1-new-date/solution.md b/1-js/05-data-types/11-date/1-new-date/solution.md
index fa8947196..a3f361ee9 100644
--- a/1-js/05-data-types/11-date/1-new-date/solution.md
+++ b/1-js/05-data-types/11-date/1-new-date/solution.md
@@ -13,6 +13,6 @@ We could also create a date from a string, like this:
```js run
//new Date(datastring)
-let d2 = new Date("February 20, 2012 03:12:00");
+let d2 = new Date("2012-02-20T03:12");
alert( d2 );
```
diff --git a/1-js/05-data-types/11-date/article.md b/1-js/05-data-types/11-date/article.md
index 8d5bcd01b..4a30bef9e 100644
--- a/1-js/05-data-types/11-date/article.md
+++ b/1-js/05-data-types/11-date/article.md
@@ -49,8 +49,15 @@ _`new Date(datestring)â`_
ÙØ¬Ø¯ ÙÙ ÙØ°Ø§ اÙÙ
ثا٠أ٠اÙÙÙØª ØºÙØ± Ù
ØØ¯Ø¯ ÙØ°Ø§ ÙÙÙ٠بتÙÙÙØª GMT Ù
ÙØªØµÙ اÙÙÙÙØ ÙÙØØ¯Ø¯ ÙÙÙÙØ§ ÙÙÙ
ÙØ·ÙØ© Ø§ÙØ²Ù
ÙÙØ© Ø§ÙØªÙ تÙÙØ° Ø§ÙØ´ÙÙØ±Ø© ضÙ
ÙÙØ§Ø ÙØ§ÙÙØªÙجة ÙÙ
Ù٠أ٠تÙÙÙ Thu Jan 26 2017 11:00:00 ÙÙØ¨Ùدا٠ذات اÙÙ
ÙØ·ÙØ© Ø§ÙØ²Ù
ÙÙØ© GMT+1100 Ø£Ù ÙÙ
Ù٠أ٠تÙÙÙ Wed Jan 25 2017 16:00:00 ÙÙØ¨Ùدا٠اÙÙØ§Ùعة Ù٠اÙÙ
ÙØ·ÙØ© Ø§ÙØ²Ù
ÙÙØ© GMT-0800.
+<<<<<<< HEAD
_`new Date(year, month, date, hours, minutes, seconds, ms)â`_
ÙÙÙØ´Ø¦ ØªØ§Ø±ÙØ®Ùا باÙÙ
ÙÙÙÙØ§Øª اÙÙ
Ù
Ø±ÙØ±Ø© ØØ³Ø¨ اÙÙ
ÙØ·ÙØ© Ø§ÙØ²Ù
ÙÙØ© اÙÙ
ØÙÙØ©. Ø£ÙÙÙ ÙØ³ÙØ·ÙÙ Ø¥ÙØ²Ø§Ù
ÙÙ٠أÙ
ا Ø§ÙØ¨ÙÙØ© Ø§Ø®ØªÙØ§Ø±ÙØ©.
+=======
+ - The `year` should have 4 digits. For compatibility, 2 digits are also accepted and considered `19xx`, e.g. `98` is the same as `1998` here, but always using 4 digits is strongly encouraged.
+ - The `month` count starts with `0` (Jan), up to `11` (Dec).
+ - The `date` parameter is actually the day of month, if absent then `1` is assumed.
+ - If `hours/minutes/seconds/ms` is absent, they are assumed to be equal `0`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ¬Ø¨ Ø£Ù ÙÙÙÙ Ø§ÙØ¹Ø§Ù
`year` بأربع Ø®Ø§ÙØ§Øª: `2013` ØµØØ `98` خطأ.
ÙØ¨Ø¯Ø£ Ø§ÙØ´Ùر `month` Ø¨Ø§ÙØ±ÙÙ
`0` (ÙÙØ§Ùر) ÙÙÙØªÙÙ Ø¨Ø§ÙØ¹Ø¯Ø¯ `11` (Ø¯ÙØ³Ù
بر).
@@ -318,7 +325,12 @@ function bench(f) {
let time1 = 0;
let time2 = 0;
+<<<<<<< HEAD
// â«ÙشغÙÙ bench(upperSlice)â Ùbench(upperLoop)â Ø¹Ø´Ø± Ù
رات Ù
Ø±ÙØ© بÙ
Ø±ÙØ©
+=======
+*!*
+// run bench(diffSubtract) and bench(diffGetTime) each 10 times alternating
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
for (let i = 0; i < 10; i++) {
time1 += bench(diffSubtract);
time2 += bench(diffGetTime);
@@ -344,7 +356,12 @@ for (let i = 0; i < 10; i++) {
**Ø§ÙØ²Ù
Ø§ÙØØ°Ø± Ù
ت٠Ù
ا Ø£Ø¬Ø±ÙØª ÙÙØ§Ø³Ø§Øª أداء عÙ٠اÙÙ
ستÙÙ Ø§ÙØ°Ø±ÙÙ**.
+<<<<<<< HEAD
تÙÙÙÙØ° Ù
ØØ±ÙÙØ§Øª Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت Ø§ÙØØ¯ÙØ«Ø© Ø¹Ø¯Ø¯ÙØ§ ÙØ¨ÙØ±ÙØ§ Ù
Ù Ø§ÙØªØØ³ÙÙØ§ØªØ ÙÙØ¯ ØªÙØºÙÙØ± ÙØªØ§Ø¦Ø¬ âØ§ÙØ§Ø®ØªØ¨Ø§Ø±Ø§Øª Ø§ÙØµÙØ§Ø¹ÙØ©â Ù
ÙØ§Ø²ÙØ©Ù âØ¨Ø§ÙØ§Ø³ØªØ¹Ù
Ø§Ù Ø§ÙØ·Ø¨Ùع٠ÙÙØ§âØ Ø®ØµÙØµÙا ØÙÙ ÙÙÙØ³ أداء Ù
ا ÙÙ ØµØºÙØ± ÙÙØºØ§ÙØ© Ù
ث٠طرÙÙØ© عÙ
Ù Ù
ÙØ¹Ø§Ù
Ù Ø±ÙØ§Ø¶ÙØ Ø£Ù Ø¯Ø§ÙØ© Ù
ضÙ
ÙÙØ© Ù٠اÙÙØºØ© ÙÙØ³Ùا. ÙÙØ°Ø§Ø ÙÙ ÙÙØª ØªØ±ÙØ¯ ØÙÙØ§ ÙÙÙ
Ø§ÙØ£Ø¯Ø§Ø¡ ÙÙ
ا ÙØ¬Ø¨Ø ÙÙ
Ù ÙØ¶Ù٠تعÙÙÙ
طرÙÙØ© عÙ
Ù Ù
ØØ±ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت. ØÙÙÙØ§ ربÙÙ
ا ÙÙ ØªØØªØ§Ø¬ ÙØ°Ù اÙÙÙØ§Ø³Ø§Øª عÙ٠اÙÙ
ستÙÙ Ø§ÙØ°Ø±ÙÙØ Ø£Ø¨Ø¯ÙØ§.
+=======
+The great pack of articles about V8 can be found at .
+```
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
ÙÙÙ Ø£Ù ØªÙØ±Ø£ بعض اÙÙ
ÙØ§Ùات Ø§ÙØ±Ø§Ø¦Ø¹Ø© ØÙÙ V8 ÙÙØ§ [http://mrale.ph](mrale.ph).
diff --git a/1-js/05-data-types/12-json/article.md b/1-js/05-data-types/12-json/article.md
index 1879928db..23580aa45 100644
--- a/1-js/05-data-types/12-json/article.md
+++ b/1-js/05-data-types/12-json/article.md
@@ -27,10 +27,14 @@ alert(user); // {name: "John", age: 30}
## JSON.stringify
+<<<<<<< HEAD
إ٠اÙÙØ§Ø¦Ù
[JSON](http://en.wikipedia.org/wiki/JSON) (JavaScript Object Notation)
ÙÙ Ø´Ù٠عاÙ
ÙØ¹Ø±Ø¶ اÙÙØ§Ø¦Ùات ÙØ§ÙÙÙÙ
. ÙÙØ¯ تÙ
ÙØµÙÙ ÙÙ
ا Ù٠ا٠[RFC 4627](http://tools.ietf.org/html/rfc4627).
ÙÙØ¯ صÙÙØ¹ ÙÙ Ø§ÙØ¨Ø¯Ø§ÙØ© Ù
Ù Ø£Ø¬Ù Ø¬Ø§ÙØ§ Ø³ÙØ±ÙØ¨ØªØ ÙÙÙÙ ÙÙØ§Ù ÙØºØ§Øª ÙÙ
ÙØªØ¨Ø§Øª أخر٠ÙÙØªØ¹Ø§Ù
Ù Ù
Ø¹Ù Ø£ÙØ¶Ùا. ÙÙØ°ÙÙ Ù
Ù Ø§ÙØ³Ù٠استخداÙ
اÙÙØ§Ø¦Ù JSON ÙØªØ¨Ø§Ø¯Ù Ø§ÙØ¨ÙØ§ÙØ§Øª Ø¹ÙØ¯Ù
ا تÙÙ٠اÙÙØ§Ø¬ÙØ© Ø¨Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØ§ÙØ³ÙØ±Ùر / Ø§ÙØ¨Ø§Ù Ø§ÙØ¯ Ø¨ÙØºØ© Ù
ث٠Ruby/PHP/Java أ٠أÙÙØ§ ÙØ§Ù.
+=======
+The [JSON](https://en.wikipedia.org/wiki/JSON) (JavaScript Object Notation) is a general format to represent values and objects. It is described as in [RFC 4627](https://tools.ietf.org/html/rfc4627) standard. Initially it was made for JavaScript, but many other languages have libraries to handle it as well. So it's easy to use JSON for data exchange when the client uses JavaScript and the server is written on Ruby/PHP/Java/Whatever.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ØªØØªÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت عÙÙ Ø¯ÙØ§Ù ÙÙØªØ¹Ø§Ù
Ù Ù
ع اÙÙØ§Ø¦Ù JSON:
@@ -45,7 +49,7 @@ let student = {
age: 30,
isAdmin: false,
courses: ['html', 'css', 'js'],
- wife: null
+ spouse: null
};
*!*
@@ -62,7 +66,7 @@ alert(json);
"age": 30,
"isAdmin": false,
"courses": ["html", "css", "js"],
- "wife": null
+ "spouse": null
}
*/
*/!*
@@ -413,7 +417,7 @@ alert( JSON.stringify(meetup) );
ÙÙÙÙØ© استخداÙ
ÙØ§:
```js
-let value = JSON.parse(str, [reviver]);
+let value = JSON.parse(str[, reviver]);
```
str
@@ -459,7 +463,11 @@ let json = `{
Ø¥ÙÙ Ø¬Ø§ÙØ¨ ذÙÙØ ÙØ§ ÙØ¯Ø¹Ù
Ø§ÙØ¬ÙسÙÙ Ø§ÙØªØ¹ÙÙÙØ§Øª (comments)Ø ØÙØ« Ø£Ù Ø¥Ø¶Ø§ÙØ© تعÙÙÙ ÙÙÙØ§Ø¦Ù Ø¬ÙØ³ÙÙ Ø³ÙØ¬Ø¹ÙÙ ØºÙØ± ØµØ§ÙØ.
+<<<<<<< HEAD
ÙÙØ§Ù بÙÙÙØ© أخر٠تسÙ
Ù [JSON5](http://json5.org/) ÙØ§Ùت٠تسÙ
Ø Ø¨Ø§ÙØ®ØµØ§Ø¦Øµ Ø§ÙØºÙر Ù
ØØ§Ø·Ø© Ø¨Ø¹ÙØ§Ù
Ø© Ø§ÙØªÙØµÙØµ Ø§ÙØ«ÙØ§Ø¦ÙØ© ÙØ§ÙتعÙÙÙØ§Øª ÙØºÙØ±ÙØ§Ø ÙÙÙÙ ÙØ°Ù Ù
ÙØªØ¨Ø© أخر٠ÙÙÙØ³Øª ÙÙ Ù
ÙØ§ØµÙات اÙÙØºØ©.
+=======
+There's another format named [JSON5](https://json5.org/), which allows unquoted keys, comments etc. But this is a standalone library, not in the specification of the language.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
إ٠اÙÙØ§Ø¦Ù JSON ÙÙ Ù
ØØ¯ÙÙØ¯ ÙØ°ÙÙ ÙÙØ³ ÙØ£Ù اÙÙ
Ø·ÙÙÙØ±ÙÙ ÙØ³ÙÙÙÙ ÙÙÙÙ ÙÙØ³Ù
Ø§Ø Ø¨Ø³Ø±Ø¹Ø© ÙØ³ÙÙÙØ© Ø®Ø·ÙØ§Øª Ø§ÙØªØÙÙÙ.
diff --git a/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md b/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
index 00bc45bdb..11175db13 100644
--- a/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
+++ b/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
@@ -37,4 +37,8 @@ alert( sumTo(100) );
Ø§ÙØ¯Ø§ÙØ© اÙÙ
ØªÙØ±Ø±Ø© تأت٠Ù٠اÙÙ
رتبة Ø§ÙØ§Ø®Ùرة ÙÙ Ø§ÙØ³Ø±Ø¹Ø© ببساطة ÙØ£ÙÙØ§ ÙÙØ°Øª اÙÙØ«Ùر Ù
٠اÙÙØ¯Ø§Ø¡Ø§Øª ٠ذÙÙ ØªØ·ÙØ¨ اÙÙØ«Ùر Ù
Ù Ø³ÙØ§Ùات Ø§ÙØªÙÙÙØ° Ù ÙÙÙ
Ø© Ø³ÙØ§Ùات Ø§ÙØªÙÙÙØ° ÙØ°ÙÙ ÙØ¥ÙÙØ§ Ø§ÙØ£Ø¨Ø·Ø£
+<<<<<<< HEAD
2. ÙØ¹Ø¶ اÙÙ
ØØ±Ùات تدعÙ
ØªØØ³ÙÙ "tail call": أذا ÙØ§Ù اÙÙØ¯Ø§Ø¡ اÙÙ
ØªÙØ±Ø± ÙÙ Ø§ÙØ£Ø®Ùر ÙÙ Ø§ÙØ¯Ø§ÙØ© (Ù
Ø«ÙÙ
ا ÙÙ`sumTo` ) إذا ÙØ§ÙØ¯Ø§ÙØ© Ø§ÙØ®Ø§Ø±Ø¬ÙØ© ÙÙ ØªØØªØ§Ø¬ Ø¥ÙÙ Ù
ÙØ§ØµÙØ© Ø§ÙØªÙÙÙØ° ÙØ¨Ø§ÙتاÙÙ ÙØ¥Ù اÙÙ
ØØ±Ù ÙØ§ ÙØØªØ§Ø¬ Ø¥ÙÙ ØªØ°ÙØ± Ø³ÙØ§Ù Ø§ÙØªÙÙÙØ°. ذÙÙ ÙØ²Ø¨Ù Ø§ÙØ¹Ø¨Ø¡ Ø¹Ù Ø§ÙØ°Ø§Ùرة ÙØ°ÙÙ Ø§ÙØ¹Ø¯ Ø¥ÙÙ `sumTo(100000)` Ù
Ù
ÙÙØ§Ù. ÙÙÙ Ù
ØØ±Ù Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙØ§ ÙØ¯Ø¹Ù
ÙØ°Ø§ Ø§ÙØªØØ³Ù٠أ٠اÙÙ
عظÙ
ÙØ§ ÙØ¯Ø¹Ù
, ÙØ°Ù٠سÙÙÙÙ ÙÙØ§Ù خطأ: ÙÙØ¯ ØªØ®Ø·ÙØª Ø§ÙØØ¬Ù
Ø§ÙØ£Ùص٠ÙÙÙÙ
Ø© Ø³ÙØ§Ù Ø§ÙØªÙÙÙØ°.
+=======
+P.P.S. Some engines support the "tail call" optimization: if a recursive call is the very last one in the function, with no other calculations performed, then the outer function will not need to resume the execution, so the engine doesn't need to remember its execution context. That removes the burden on memory. But if the JavaScript engine does not support tail call optimization (most of them don't), there will be an error: maximum stack size exceeded, because there's usually a limitation on the total stack size.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md
index 8660aa30e..eb03a34f8 100644
--- a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md
+++ b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md
@@ -34,7 +34,11 @@ printReverseList(list);
# ØÙ Ø§ÙØÙÙØ©
+<<<<<<< HEAD
ØÙ Ø§ÙØÙÙØ© ÙÙ Ø§ÙØ§Ø®Ø± ÙØ¹ØªØ¨Ø± Ù
Ø¹ÙØ¯ ÙÙÙÙØ§Ù باÙÙØ³Ø¨Ø© Ø¥ÙÙ Ø§ÙØ·Ø¨Ø§Ø¹Ø© اÙÙ
باشرة.
+=======
+The loop variant is also a little bit more complicated than the direct output.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØÙ ÙØ§ ÙÙ
تÙ٠طرÙÙÙØ© ÙÙØØµÙ٠عÙ٠اÙÙÙÙ
Ø© Ø§ÙØ£Ø®Ùرة Ù٠اÙÙØ§Ø¦Ù
Ø© ÙÙØ§ ÙØ³ØªØ·Ùع Ø§ÙØ¹Ùدة ÙÙØ®ÙÙ.
diff --git a/1-js/06-advanced-functions/01-recursion/article.md b/1-js/06-advanced-functions/01-recursion/article.md
index ea5da247c..992661960 100644
--- a/1-js/06-advanced-functions/01-recursion/article.md
+++ b/1-js/06-advanced-functions/01-recursion/article.md
@@ -286,7 +286,11 @@ function pow(x, n) {
**Ø£Ù Ø¯Ø§ÙØ© Ù
ØªÙØ±Ø±Ø© "Recursive" ÙÙ
ÙÙ Ø£Ù ÙØ¹Ùد ÙØªØ§Ø¨ØªÙا بطرÙÙØ© Ø§ÙØªÙرار "Iterative".ÙØ¯Ø§Ø¦Ù
ا٠Ù
ا ÙÙÙÙ Ø§ÙØªÙرار بإستخداÙ
Ø§ÙØÙÙØ§Øª Ø£ÙØ«Ø± ÙÙØ§Ø¡Ø©.**
+<<<<<<< HEAD
ÙÙ٠أØÙØ§ÙØ§Ù إعادة ÙØªØ§Ø¨Ø© Ø§ÙØ¯Ø§ÙØ© بطرÙÙØ© Ø§ÙØªÙرار ÙØ§ ÙÙÙ٠سÙÙØ§Ù Ø£Ø¨Ø¯Ø§Ù Ø®ØµÙØµØ§Ù Ø¹ÙØ¯Ù
ا تÙÙÙ Ø§ÙØ¯Ø§ÙØ© Ø§ÙØ®Ø§Ø±Ø¬ÙØ© تعتÙ
د عÙÙ Ø£ÙØ«Ø± Ù
Ù Ø¯Ø§ÙØ© داخÙÙØ© ÙØ´Ø±ÙØ· ÙØ«Ùرة ÙØ§ÙÙØ«Ùرة Ù
Ù ÙØ±Ùع Ø§ÙØ´Ø±ÙØ·. ÙÙ ÙØ°Ø§ ÙØ¬Ø¹ÙÙ ÙØ§ ØªØ³ØªØ·ÙØ¹ إعادة ÙØªØ§Ø¨ØªÙا Ù
رة Ø£Ø®Ø±Ù Ø¨Ø·Ø±ÙØ© Ø§ÙØÙÙØ§Øª.
+=======
+...But sometimes the rewrite is non-trivial, especially when a function uses different recursive subcalls depending on conditions and merges their results or when the branching is more intricate. And the optimization may be unneeded and totally not worth the efforts.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø§ÙØ¯Ø§ÙØ© اÙÙ
ØªÙØ±Ø±Ø© "Recursion" تعطÙÙ ÙÙØ¯ Ø£ÙØµØ± ÙØ£Ø³ÙÙ Ù٠اÙÙØ±Ø§Ø¡Ø©. ÙØ¶Ø¹ Ù٠إعتبار٠أ٠تØÙÙÙ Ø§ÙØ§Ø³ØªØ®Ø¯Ø§Ù
Ø§ÙØ£Ù
ث٠ÙÙØ³ Ù
Ø·ÙÙØ¨Ø§Ù ÙÙ ÙÙ Ø§ÙØØ§ÙØ§Øª Ù٠بعض Ø§ÙØØ§ÙØ§Øª Ø£ÙØª ÙÙØ· ØªØ±ÙØ¯ ÙÙØ¯ Ø¬ÙØ¯Ø§Ù.
@@ -545,7 +549,11 @@ list.next = list.next.next;
Ø¹ÙØ¯Ù
ا ØªÙØ§Ø¯Ù Ø§ÙØ¯Ø§ÙØ© ÙÙØ³Ùا, ÙØ°Ø§ ÙØ³Ù
Ù *Ø®Ø·ÙØ© Ù
ØªÙØ±Ø±Ø©*. Ø§ÙØ§Ø³Ø§Ø³ ÙÙØ¯Ø§ÙØ© اÙÙ
ØªÙØ±Ø±Ø© ÙØ¹ØªØ¨Ø± أبسط ØµÙØ±Ø© ÙÙØ¯Ø§ÙØ© ÙÙØ§ ÙÙ
ÙÙ Ù
ÙØ§Ø¯Ø§Ø© Ø§ÙØ¯Ø§ÙØ© Ù
رة أخر٠ÙÙÙÙØ§ ÙØ°Ø§ Ø§ÙØ´Ø±Ø· Ø³ØªØ¸Ù Ø§ÙØ¯Ø§ÙØ© ØªÙØ§Ø¯Ù ÙÙØ³Ùا Ø¥ÙÙ Ù
ا ÙØ§ ÙÙØ§ÙØ©.
+<<<<<<< HEAD
- اÙÙ [تعرÙ٠اÙÙ
ØªÙØ±Ø±](https://en.wikipedia.org/wiki/Recursive_data_type) ÙØ¹ØªØ¨Ø± ÙÙÙÙ Ø¨ÙØ§Ùات ÙØ¹Ø±Ù ÙÙØ³Ù بÙÙØ³Ù ع٠طرÙÙ Ø§ÙØªÙرار.
+=======
+ Trees like HTML elements tree or the department tree from this chapter are also naturally recursive: they have branches and every branch can have other branches.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù
Ø«ÙØ§Ù اÙÙØ§Ø¦Ù
Ø© اÙÙ
ØªØµÙØ© ÙÙ
Ù٠تعرÙÙÙØ§ عÙ٠أÙÙØ§ ÙÙÙÙ Ø¨ÙØ§Ùات تتÙÙÙ Ù
٠شئ object ÙØ´Ùر Ø¥Ù٠اÙÙØ§Ø¦Ù
Ø© ÙÙØ³Ùا.
diff --git a/1-js/06-advanced-functions/02-rest-parameters-spread/article.md b/1-js/06-advanced-functions/02-rest-parameters-spread/article.md
index 422ef82e2..4929be804 100644
--- a/1-js/06-advanced-functions/02-rest-parameters-spread/article.md
+++ b/1-js/06-advanced-functions/02-rest-parameters-spread/article.md
@@ -26,7 +26,11 @@ function sum(a, b) {
alert( sum(1, 2, 3, 4, 5) );
```
+<<<<<<< HEAD
Ù٠تر٠أÙ٠خطأ بسبب تÙ٠اÙÙÙØ³Ø·Ø§Ø¡ Â«Ø§ÙØ²Ø§Ø¦Ø¯Ø©Â». ÙÙÙÙ Ø·Ø¨Ø¹ÙØ§ ÙØ§ÙÙØªÙجة Ù٠تأخذ Ø¨Ø§ÙØØ³Ø¨Ø§Ù Ø¥ÙØ§ Ø£ÙÙ٠اثÙÙÙ.
+=======
+There will be no error because of "excessive" arguments. But of course in the result only the first two will be counted, so the result in the code above is `3`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
Ù٠تضÙ
Ù٠بÙÙØ© اÙÙ
ÙØ¹Ø§Ù
ÙØ§Øª Ù٠تعرÙÙ Ø§ÙØ¯Ø§ÙØ© باستعÙ
Ø§Ù Ø§ÙØ«Ùاث ÙÙØ§Ø· `â...â` Ø«Ù
٠اسÙ
اÙÙ
صÙÙÙØ© Ø§ÙØªÙ Ø³ØªØØªÙÙÙÙ
. تعÙ٠تÙ٠اÙÙÙØ· ØØ±ÙÙÙØ§ «اجÙ
ع اÙÙ
ÙØ¹Ø§Ù
ÙØ§Øª Ø§ÙØ¨Ø§ÙÙØ© ÙÙ Ù
صÙÙÙØ©Â».
diff --git a/1-js/06-advanced-functions/03-closure/10-make-army/solution.md b/1-js/06-advanced-functions/03-closure/10-make-army/solution.md
index e3261a6f8..4ff2f2fbd 100644
--- a/1-js/06-advanced-functions/03-closure/10-make-army/solution.md
+++ b/1-js/06-advanced-functions/03-closure/10-make-army/solution.md
@@ -45,7 +45,105 @@
3. ÙØªÙ
إرجاع اÙÙ
صÙÙÙØ© Ù
Ù Ø§ÙØ¯Ø§ÙØ©.
+<<<<<<< HEAD
Ø«Ù
ÙÙ ÙÙØª ÙØ§ØÙØ Ø³ÙØªÙ
استدعاء Ø£Ù Ø¹Ø¶ÙØ عÙ٠سبÙ٠اÙÙ
ثا٠`army[5]()`Ø ÙØ³ÙتÙ
Ø§ÙØØµÙ٠عÙÙ Ø§ÙØ¹Ùصر `army[5]` Ù
٠اÙÙ
صÙÙÙØ© (ÙÙÙ Ø¯Ø§ÙØ©) ÙÙØªÙ
Ø§Ø³ØªØ¯Ø¹Ø§Ø¤ÙØ§.
+=======
+3. The array is returned from the function.
+
+ Then, later, the call to any member, e.g. `army[5]()` will get the element `army[5]` from the array (which is a function) and calls it.
+
+ Now why do all such functions show the same value, `10`?
+
+ That's because there's no local variable `i` inside `shooter` functions. When such a function is called, it takes `i` from its outer lexical environment.
+
+ Then, what will be the value of `i`?
+
+ If we look at the source:
+
+ ```js
+ function makeArmy() {
+ ...
+ let i = 0;
+ while (i < 10) {
+ let shooter = function() { // shooter function
+ alert( i ); // should show its number
+ };
+ shooters.push(shooter); // add function to the array
+ i++;
+ }
+ ...
+ }
+ ```
+
+ We can see that all `shooter` functions are created in the lexical environment of `makeArmy()` function. But when `army[5]()` is called, `makeArmy` has already finished its job, and the final value of `i` is `10` (`while` stops at `i=10`).
+
+ As the result, all `shooter` functions get the same value from the outer lexical environment and that is, the last value, `i=10`.
+
+ 
+
+ As you can see above, on each iteration of a `while {...}` block, a new lexical environment is created. So, to fix this, we can copy the value of `i` into a variable within the `while {...}` block, like this:
+
+ ```js run
+ function makeArmy() {
+ let shooters = [];
+
+ let i = 0;
+ while (i < 10) {
+ *!*
+ let j = i;
+ */!*
+ let shooter = function() { // shooter function
+ alert( *!*j*/!* ); // should show its number
+ };
+ shooters.push(shooter);
+ i++;
+ }
+
+ return shooters;
+ }
+
+ let army = makeArmy();
+
+ // Now the code works correctly
+ army[0](); // 0
+ army[5](); // 5
+ ```
+
+ Here `let j = i` declares an "iteration-local" variable `j` and copies `i` into it. Primitives are copied "by value", so we actually get an independent copy of `i`, belonging to the current loop iteration.
+
+ The shooters work correctly, because the value of `i` now lives a little bit closer. Not in `makeArmy()` Lexical Environment, but in the Lexical Environment that corresponds to the current loop iteration:
+
+ 
+
+ Such a problem could also be avoided if we used `for` in the beginning, like this:
+
+ ```js run demo
+ function makeArmy() {
+
+ let shooters = [];
+
+ *!*
+ for(let i = 0; i < 10; i++) {
+ */!*
+ let shooter = function() { // shooter function
+ alert( i ); // should show its number
+ };
+ shooters.push(shooter);
+ }
+
+ return shooters;
+ }
+
+ let army = makeArmy();
+
+ army[0](); // 0
+ army[5](); // 5
+ ```
+
+ That's essentially the same, because `for` on each iteration generates a new lexical environment, with its own variable `i`. So `shooter` generated in every iteration references its own `i`, from that very iteration.
+
+ 
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø§ÙØ³Ø¤Ø§Ù ÙÙ ÙÙ
اذا ØªØ¸ÙØ± ÙØ¬Ù
ÙØ¹ Ø§ÙØ¯Ùا٠ÙÙØ³ اÙÙÙÙ
Ø©Ø ÙÙÙ Ø§ÙØ±ÙÙ
`10`Ø
diff --git a/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md b/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md
index ae8b582db..35fc1ac8f 100644
--- a/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md
+++ b/1-js/06-advanced-functions/03-closure/5-function-in-if/task.md
@@ -1,8 +1,14 @@
+importance: 5
+<<<<<<< HEAD
### Ø¯Ø§ÙØ© Ù٠شرط if
طاÙÙØ¹ Ø§ÙØ´ÙÙØ±Ø© أسÙÙÙ. Ù
ا ÙØ§ØªØ¬ Ø§ÙØ§Ø³ØªØ¯Ø¹Ø§Ø¡ Ù٠آخر سطرØ
+=======
+---
+# Function in if
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
diff --git a/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md
index 975c14d2e..e69ca5321 100644
--- a/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md
+++ b/1-js/06-advanced-functions/03-closure/7-let-scope/solution.md
@@ -24,8 +24,14 @@ In this example we can observe the peculiar difference between a "non-existing"
```js
function func() {
*!*
+<<<<<<< HEAD
// اÙÙ
ØªØºÙØ± اÙÙ
ØÙÙ X ÙØ¹ØªØ¨Ø± Ù
عرÙÙ ÙÙÙ
ØØ±Ù Ù
Ù Ø§ÙØ¨Ø¯Ø§ÙØ©, ÙÙÙ **ØºÙØ± Ù
عر٠بÙÙÙ
Ø©** ØªØ¸Ù ØØªÙ let
// ÙØ°ÙÙ ÙÙØ§Ù خطأ
+=======
+ // the local variable x is known to the engine from the beginning of the function,
+ // but "uninitialized" (unusable) until let ("dead zone")
+ // hence the error
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
*/!*
console.log(x); // ReferenceError: ÙØ§ ÙØ³ØªØ·Ùع اÙÙØµÙÙ ÙÙ 'x' ÙØ¨Ù Ø¥Ø¹Ø·Ø§Ø¦ÙØ§ ÙÙÙ
Ø©
diff --git a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js
index e3c335e03..802f28c4d 100644
--- a/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js
+++ b/1-js/06-advanced-functions/03-closure/9-sort-by-field/_js.view/test.js
@@ -23,7 +23,7 @@ describe("byField", function(){
{ name: "John", age: 20, surname: "Johnson"},
];
let ageSortedAnswer = users.sort(byField("age"));
- assert.deepEqual(ageSortedKey, ageSortedKey);
+ assert.deepEqual(ageSortedKey, ageSortedAnswer);
});
it("sorts users by surname", function(){
diff --git a/1-js/06-advanced-functions/03-closure/article.md b/1-js/06-advanced-functions/03-closure/article.md
index a158647e6..4146f970b 100644
--- a/1-js/06-advanced-functions/03-closure/article.md
+++ b/1-js/06-advanced-functions/03-closure/article.md
@@ -7,7 +7,11 @@
ÙÙÙÙ Ù
اذا ÙØØ¯Ø« إذا ØªØºÙØ±Øª اÙÙ
ØªØºÙØ±Ø§Øª Ø§ÙØ®Ø§Ø±Ø¬ÙØ© بعد Ø¥ÙØ´Ø§Ø¡ Ø§ÙØ¯Ø§ÙØ©Ø ÙÙ Ø³ØªØØµÙ Ø§ÙØ¯Ø§ÙØ© عÙ٠اÙÙÙÙ
Ø§ÙØ£ØØ¯Ø« Ø£Ù
اÙÙÙÙ
اÙÙØ¯ÙÙ
Ø©Ø
+<<<<<<< HEAD
ÙÙ
اذا إذا تÙ
تÙ
Ø±ÙØ± Ø¯Ø§ÙØ© ÙÙ
عÙÙ
Ø© ÙØ§Ø³ØªØ¯Ø¹Ø§Ø¤Ùا Ù
Ù Ù
ÙØ§Ù آخر Ù٠اÙÙÙØ¯Ø ÙÙ Ø³ØªØØµÙ Ø§ÙØ¯Ø§ÙØ© عÙÙ ÙØµÙ٠إÙ٠اÙÙ
ØªØºÙØ±Ø§Øª Ø§ÙØ®Ø§Ø±Ø¬ÙØ© Ù٠اÙÙ
ÙØ§Ù Ø§ÙØ¬Ø¯ÙدØ
+=======
+And what if a function is passed along as an argument and called from another place of code, will it get access to outer variables at the new place?
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¯Ø¹ÙØ§ ÙÙØ³Ø¹ Ù
Ø¹Ø±ÙØªÙا ÙÙÙÙ
ÙØ°Ù Ø§ÙØ³ÙÙØ§Ø±ÙÙÙØ§Øª ÙØ§ÙسÙÙØ§Ø±ÙÙÙØ§Øª Ø§ÙØ£Ùثر تعÙÙØ¯Ùا.
@@ -155,7 +159,11 @@ alert(counter()); // 2
ÙÙÙ ÙØ¹Ù
Ù ÙØ°Ø§Ø Ù٠إذا ØµÙØ¹Ùا عدادات ÙØ«Ùر سÙÙÙÙÙØ§ ØºÙØ± Ù
عتÙ
دÙ٠عÙ٠بعضÙÙ
Ø Ù
اذا ÙØØ¯Ø« Ù
ع اÙÙ
ØªØºÙØ±Ø§Øª ÙÙØ§Ø
+<<<<<<< HEAD
ÙÙÙ
ÙØ°Ù Ø§ÙØ£Ø´Ùاء ÙØ¹Ø¯ عظÙÙ
ا٠ÙÙÙ
عÙÙÙ
ات Ø§ÙØ´Ø§Ù
ÙØ© ÙØ¬Ø§Ùا Ø³ÙØ±Ùبت ÙÙ
ÙÙØ¯ جدا٠ÙÙ ØØ§ÙØ© Ø§ÙØ³ÙÙØ§Ø±ÙÙÙØ§Øª اÙÙ
Ø¹ÙØ¯Ø©. ÙØ°ÙÙ ÙÙØ§ ÙØªØ¹Ù
Ù Ø£ÙØ«Ø± Ù٠أÙ
ÙØ± Ø£ÙØ«Ø± ØµØ¹ÙØ¨Ø© ÙØªØØªØ§Ø¬ Ø¥Ù٠ترÙÙØ².
+=======
+Understanding such things is great for the overall knowledge of JavaScript and beneficial for more complex scenarios. So let's go a bit in-depth.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## Ø§ÙØ¨Ùئات اÙÙ
عجÙ
ÙØ©
diff --git a/1-js/06-advanced-functions/04-var/article.md b/1-js/06-advanced-functions/04-var/article.md
index 8b01fb9b0..cbb20a2b6 100644
--- a/1-js/06-advanced-functions/04-var/article.md
+++ b/1-js/06-advanced-functions/04-var/article.md
@@ -3,6 +3,13 @@
```smart header="ÙØ°Ù اÙÙ
ÙØ§ÙØ© Ù
٠أج٠ÙÙÙ
اÙÙØµÙص اÙÙØ¯ÙÙ
Ø©"
اÙÙ
عÙÙÙ
ات Ø¯Ø§Ø®Ù ÙØ°Ù اÙÙ
ÙØ§ÙØ© ØªØ³Ø§Ø¹Ø¯ÙØ§ ÙÙ ÙÙÙ
اÙÙØµÙص اÙÙØ¯ÙÙ
Ø© Ø£ÙØ«Ø± ÙÙØ§ ØªØØªÙ٠عÙ٠أ٠Ù
عÙÙÙ
ات ع٠ÙÙÙÙØ© ÙØªØ§Ø¨Ø© ÙÙØ¯ Ø¬Ø¯ÙØ¯
+<<<<<<< HEAD
+=======
+```smart header="This article is for understanding old scripts"
+The information in this article is useful for understanding old scripts.
+
+That's not how we write new code.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
Ø°ÙØ±Ùا ÙÙ Ø£ÙØ§Ø¦Ù اÙÙØµÙÙ ØÙ٠تÙÙÙ
ÙØ§ ع٠[اÙÙ
ØªØºÙØ±Ø§Øª](info:variables), Ø°ÙØ±Ùا Ø«ÙØ§Ø« طرائ٠ÙÙØªØµØ±ÙØ Ø¹ÙÙØ§:
@@ -76,7 +83,7 @@ alert(test); // ReferenceError: test is not defined
````
ÙØ³Ø±Ù Ø§ÙØ£Ù
ر ذات٠عÙÙ Ø§ÙØÙÙØ§Øª ÙÙØ§ ÙÙ
Ù٠أ٠ÙÙÙÙ `âvarâ` Ù
ØÙÙÙØ§ ØØ³Ø¨ اÙÙØªÙØ© Ø£Ù ØØ³Ø¨ Ø§ÙØÙÙØ©:
-```js
+```js run
for (var i = 0; i < 10; i++) {
var one = 1;
// ...
@@ -268,11 +275,11 @@ function go() {
```js run
// Ways to create IIFE
-(function() {
+*!*(*/!*function() {
alert("Parentheses around the function");
}*!*)*/!*();
-(function() {
+*!*(*/!*function() {
alert("Parentheses around the whole thing");
}()*!*)*/!*;
diff --git a/1-js/06-advanced-functions/05-global-object/article.md b/1-js/06-advanced-functions/05-global-object/article.md
index 24fe68844..ce2aed158 100644
--- a/1-js/06-advanced-functions/05-global-object/article.md
+++ b/1-js/06-advanced-functions/05-global-object/article.md
@@ -24,7 +24,7 @@ var gVar = 5;
alert(window.gVar); // â«5 (ØªØµÙØ± Ø®Ø§ØµÙØ© Ù
Ù Ø®Ø§ØµÙØ§Øª اÙÙØ§Ø¦Ù Ø§ÙØ¹Ù
ÙÙ
Ù)
```
-The same effect have function declarations (statements with `function` keyword in the main code flow, not function expressions).
+Function declarations have the same effect (statements with `function` keyword in the main code flow, not function expressions).
Please don't rely on that! This behavior exists for compatibility reasons. Modern scripts use [JavaScript modules](info:modules) where such a thing doesn't happen.
diff --git a/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/solution.md b/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/solution.md
index e66eecae8..8fd645346 100644
--- a/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/solution.md
+++ b/1-js/06-advanced-functions/06-function-object/5-sum-many-brackets/solution.md
@@ -56,6 +56,10 @@ function f(b) {
}
```
+<<<<<<< HEAD
ÙØ³ØªÙستعÙ
Ù `âfâ` ÙØ°Ù ÙÙ Ø§ÙØ§Ø³ØªØ¯Ø¹Ø§Ø¡ Ø§ÙØªØ§ÙÙØ ÙØªÙØ¹ÙØ¯ ÙÙØ³Ùا ثاÙÙØ©Ù Ù
ÙÙ
ا ÙØ²Ù
. ÙØ¨Ø¹Ø¯Ùا ØÙÙ ÙØ³ØªØ¹Ù
Ù Ø§ÙØ¹Ø¯Ø¯ Ø£Ù Ø§ÙØ³ÙØ³ÙØ© اÙÙØµÙØ©Ø ÙÙØ¹Ùد Ø§ÙØªØ§Ø¨Ùع `âtoStringâ` اÙÙ
جÙ
ÙØ¹ `âcurrentSumâ`. ÙÙ
ÙÙ Ø£ÙØ¶Ùا Ø£Ù ÙØ³ØªØ¹Ù
Ù `âSymbol.toPrimitiveâ` Ø£Ù `âvalueOfâ` ÙØ¥Ø¬Ø±Ø§Ø¡ عÙ
ÙÙØ© Ø§ÙØªØÙÙÙ.
ترجÙ
Ø© -ÙØ¨ØªØµØ±Ù- ÙÙÙØµÙ [Function object, NFE](https://javascript.info/function-object) Ù
Ù ÙØªØ§Ø¨ [The JavaScript language](https://javascript.info/js)
+=======
+This `f` will be used in the next call, again return itself, as many times as needed. Then, when used as a number or a string -- the `toString` returns the `currentSum`. We could also use `Symbol.toPrimitive` or `valueOf` here for the conversion.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/06-advanced-functions/06-function-object/article.md b/1-js/06-advanced-functions/06-function-object/article.md
index 42f3b5602..35ee6924e 100644
--- a/1-js/06-advanced-functions/06-function-object/article.md
+++ b/1-js/06-advanced-functions/06-function-object/article.md
@@ -334,7 +334,7 @@ welcome(); // Hello, Guest (nested call works)
```smart header="ÙØ§ ÙÙØ¬Ø¯ ÙØ°Ø§ Ø§ÙØ´ÙØ¡ Ù٠تعرÙÙ Ø§ÙØ¯Ø§ÙØ© Ø§ÙØ¹Ø§Ø¯ÙØ©"
-The outer code still has its variable `sayHi` or `welcome`. And `func` is an "internal function name", how the function can call itself internally.
+The outer code still has its variable `sayHi` or `welcome`. And `func` is an "internal function name", the way for the function to call itself reliably.
Ù٠بعض Ø§ÙØ£ØÙØ§Ù Ø¹ÙØ¯Ù
ا ÙØØªØ§Ø¬ Ø¥Ù٠اسÙ
داخÙÙ ÙÙÙÙ ÙØ°Ø§ Ø§ÙØ³Ø¨Ø¨ ÙØªØÙÙ٠تعرÙÙ Ø§ÙØ¯Ø§ÙØ© Ø¥ÙÙ NFE Ø£Ù ØªØ¹Ø¨ÙØ± Ø§ÙØ¯Ø§ÙØ© اÙÙ
ÙØ³Ù
Ù.
diff --git a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md
index 8afeb08f7..7df8fd674 100644
--- a/1-js/06-advanced-functions/08-settimeout-setinterval/article.md
+++ b/1-js/06-advanced-functions/08-settimeout-setinterval/article.md
@@ -27,7 +27,11 @@ let timerId = setTimeout(func|code, [delay], [arg1], [arg2], ...)
: The delay before run, in milliseconds (1000 ms = 1 second), by default 0.
`arg1`, `arg2`...
+<<<<<<< HEAD
: ÙÙØ³Ø·Ø§Ø¡ Ø§ÙØ¯Ø§ÙØ© (ÙÙØ³Øª Ù
دعÙÙ
Ø© ÙÙ IE9-â)
+=======
+: Arguments for the function
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¥ÙÙÙ ÙØ°Ù Ø§ÙØ´ÙÙØ±Ø© Ø§ÙØªÙ تستدع٠âsayHi()â Ø¨Ø¹Ø¯ ثاÙÙØ©Ù ÙØ§ØØ¯Ø©:
@@ -102,7 +106,11 @@ alert(timerId); // same identifier (doesn't become null after canceling)
Again, there is no universal specification for these methods, so that's fine.
+<<<<<<< HEAD
ÙÙ
ÙÙÙ Ù
راجعة Ù
ÙØ§ØµÙØ© HTML5 ÙÙÙ
ؤÙÙØªØ§Øª (داخ٠اÙÙ
تصÙÙØØ§Øª) ÙÙ ÙØµÙ اÙÙ
ؤÙÙØªØ§Øª.
+=======
+For browsers, timers are described in the [timers section](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) of HTML Living Standard.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## setInterval
@@ -221,7 +229,11 @@ Did you notice?

+<<<<<<< HEAD
**تضÙ
Ù âsetTimeoutâ Ø§ÙÙ
ØªØ¯Ø§Ø®ÙØ© ÙÙØ§ Ø§ÙØªØ£Ø®Ùر Ø§ÙØ«Ø§Ø¨Øª (100 Ù
ÙÙØ«Ø§ÙÙØ© ÙÙ ØØ§ÙØªÙØ§).**
+=======
+**The nested `setTimeout` ensures a minimum delay (100ms here) between the end of one call and the beginning of the subsequent one.**
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
That's because a new call is planned at the end of the previous one.
@@ -235,7 +247,11 @@ setTimeout(function() {...}, 100);
For `setInterval` the function stays in memory until `clearInterval` is called.
+<<<<<<< HEAD
ÙÙÙÙ ÙÙØ§Ù ØªØ£Ø«ÙØ± Ø¬Ø§ÙØ¨Ù ÙØ°ÙÙ ÙØ§ÙØ¹Ø§Ø¯Ø©Ø ÙØ§ÙØ¯ÙØ§Ù ØªÙØ´Ùر Ø¥ÙÙ Ø¨ÙØ¦ØªÙا اÙÙ
ÙØ¹Ø¬Ù
ÙØ© Ø§ÙØ®Ø§Ø±Ø¬ÙØ©. ÙØ°Ø§ طاÙÙ
ا Â«ØªØ¹ÙØ´Â»Ø ØªØ¹ÙØ´ Ù
Ø¹ÙØ§ اÙÙ
ØªØºÙØ±Ø§Øª Ø§ÙØ®Ø§Ø±Ø¬ÙØ© Ø£ÙØ¶ÙØ§Ø ÙÙ٠أØÙاÙÙØ§ ÙØ¨Ùرة تأخذ Ø°Ø§ÙØ±Ø© Ø£ÙØ¨Ø± Ù
Ù Ø§ÙØ¯Ø§ÙØ© Ø°Ø§ØªÙØ§. ÙØ°Ø§Ø Ù
ت٠Ù
ا ÙÙ
ترد تÙÙ Ø§ÙØ¯Ø§ÙØ© اÙÙ
ÙØ¬Ø¯ÙÙØ© ÙØ§ÙØ£ÙØ¶Ù أ٠تÙÙØºÙÙØ§ ØØªÙÙ ÙÙ ÙØ§Ùت ØµØºÙØ±Ø© Ø¬Ø¯ÙØ§.
+=======
+There's a side effect. A function references the outer lexical environment, so, while it lives, outer variables live too. They may take much more memory than the function itself. So when we don't need the scheduled function anymore, it's better to cancel it, even if it's very small.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
````
## جدÙÙØ© setTimeout Ø¨ØªØ£Ø®ÙØ± ØµÙØ±
@@ -258,8 +274,13 @@ alert('Hello');
ÙÙ
ا Ø£ÙÙ ÙÙØ§Ù استعÙ
Ø§ÙØ§Øª Ù
ØªÙØ¯ÙÙ
Ø© خصÙÙØµÙا ÙÙÙ
تصÙÙØØ§Øª ÙÙÙ
ÙÙØ© Ø¨Ø§ÙØªØ£Ø®Ùر ØµÙØ± ÙØ°ÙØ ÙØ³ÙشرØÙا Ù٠اÙÙØµÙ «ØÙÙØ© Ø§ÙØ£ØØ¯Ø§Ø«: اÙÙ
ÙØ§Ù
عÙ٠اÙÙ
ستÙÙÙÙ Ø§ÙØ¬ÙسÙÙ
Ù ÙØ§ÙذرÙÙ».
+<<<<<<< HEAD
````smart header="Ù٠اÙÙØ§ÙØ¹Ø ÙØ§ÙØªØ£Ø®ÙØ± Ø§ÙØµÙر ÙØ°Ø§ ÙÙØ³ ØµÙØ±Ùا (Ù٠اÙÙ
تصÙÙØØ§Øª)"
ØªØØ¯Ù اÙÙ
تصÙÙØØ§Øª Ù
Ù Ø§ÙØªØ£Ø®Ùر بÙ٠تشغÙ٠اÙÙ
ؤÙÙØªØ§Øª اÙÙ
ØªØ¯Ø§Ø®ÙØ©. تÙÙÙ Ù
ÙØ§ØµÙØ© [HTML5 standard](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) HTML5: «بعد اÙÙ
ؤÙÙØªØ§Øª اÙÙ
ØªØ¯Ø§Ø®ÙØ© Ø§ÙØ®Ù
سة Ø§ÙØ£ÙÙÙØ ØªÙØ¬Ø¨Ø± اÙÙØªØ±Ø© ÙØªÙÙ٠أربع Ù
ÙÙØ«Ùا٠عÙÙ Ø§ÙØ£ÙÙ.».
+=======
+````smart header="Zero delay is in fact not zero (in a browser)"
+In the browser, there's a limitation of how often nested timers can run. The [HTML Living Standard](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) says: "after five nested timers, the interval is forced to be at least 4 milliseconds.".
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ±Ù Ù
ا ÙØ¹Ù٠ذÙÙ Ø¨ÙØ°Ø§ اÙÙ
ثا٠أسÙÙÙ. ÙÙØ¹Ùد استدعاء âsetTimeoutâ Ø¬Ø¯ÙÙØ© ÙÙØ³Ù بÙ
Ø¯ÙØ© ØªØ£Ø®ÙØ± تساÙÙ ØµÙØ±Ø ÙÙØªØ°ÙÙØ± Ù٠استدعاء اÙÙÙØª اÙÙØ¹Ù٠بÙÙÙ ÙØ¨Ù٠آخر استدعاء ÙÙ Ù
صÙÙÙØ© âtimesâ. ÙÙÙÙØ Ù
ا ÙÙ Ø§ÙØªØ£Ø®Ùرات اÙÙØ¹ÙÙØ©Ø ÙÙØ±Ù بأعÙÙÙØ§:
@@ -297,7 +318,14 @@ For server-side JavaScript, that limitation does not exist, and there exist othe
ÙØ§ØØ¸ بأÙÙ ØªÙØ§Ø¨Ùع Ø§ÙØ¬Ø¯ÙÙØ© ÙØ§ تضÙ
Ù Ø§ÙØªØ£Ø®Ùر ÙÙ
ا ÙÙ ØØ±ÙÙÙØ§.
+<<<<<<< HEAD
ÙÙ
Ø«ÙÙØ§ ÙÙ
Ù٠أ٠تÙÙÙ Ù
ؤÙÙØªØ§Øª اÙÙ
تصÙÙØØ§Øª أبطأ ÙØ£Ø³Ø¨Ø§Ø¨ Ø¹Ø¯ÙØ¯Ø©:
+=======
+For example, the in-browser timer may slow down for a lot of reasons:
+- The CPU is overloaded.
+- The browser tab is in the background mode.
+- The laptop is on battery saving mode.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
- اÙÙ
Ø¹Ø§ÙØ¬ Ù
ÙØ«ÙÙ Ø¨Ø§ÙØ¹Ù
ÙÙØ§Øª.
- اÙÙ
تصÙÙØ ÙØ¹Ù
Ù ÙÙ Ø§ÙØ®ÙÙÙØ©.
diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md
index cf851f771..6950664be 100644
--- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md
+++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/solution.md
@@ -12,11 +12,10 @@ function throttle(func, ms) {
savedThis = this;
return;
}
+ isThrottled = true;
func.apply(this, arguments); // (1)
- isThrottled = true;
-
setTimeout(function() {
isThrottled = false; // (3)
if (savedArgs) {
diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md
index 6df7af132..cbd473196 100644
--- a/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md
+++ b/1-js/06-advanced-functions/09-call-apply-decorators/04-throttle/task.md
@@ -8,7 +8,7 @@ Create a "throttling" decorator `throttle(f, ms)` -- that returns a wrapper.
When it's called multiple times, it passes the call to `f` at maximum once per `ms` milliseconds.
-The difference with debounce is that it's completely different decorator:
+Compared to the debounce decorator, the behavior is completely different:
- `debounce` runs the function once after the "cooldown" period. Good for processing the final result.
- `throttle` runs it not more often than given `ms` time. Good for regular updates that shouldn't be very often.
diff --git a/1-js/06-advanced-functions/09-call-apply-decorators/article.md b/1-js/06-advanced-functions/09-call-apply-decorators/article.md
index 6bd5650fc..6ce7d1c20 100644
--- a/1-js/06-advanced-functions/09-call-apply-decorators/article.md
+++ b/1-js/06-advanced-functions/09-call-apply-decorators/article.md
@@ -288,19 +288,34 @@ func.apply(context, args)
أ٠أÙÙ Ø§ÙØ§Ø³ØªØ¯Ø¹Ø§Ø¡ÙÙ Ø§ÙØ¢ØªÙÙ Ù
تساÙÙÙÙ ØªÙØ±ÙØ¨ÙØ§:
+<<<<<<< HEAD
```
func.call(context, ...args); // ÙÙ
Ø±ÙØ± اÙÙØ§Ø¦Ù ÙØ§Ø¦Ù
ة٠بÙ
ÙØ¹Ø§Ù
Ù Ø§ÙØªÙØ²ÙØ¹
func.apply(context, args); // â«ÙÙØ³ اÙÙÙØ±Ø© باستعÙ
ا٠apply
```
ÙÙÙÙ ÙÙØ§Ù ÙØ±Ù Ø¨Ø³ÙØ· ÙØ§ØØ¯:
+=======
+```js
+func.call(context, ...args);
+func.apply(context, args);
+```
+
+They perform the same call of `func` with given context and arguments.
+
+There's only a subtle difference regarding `args`:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
- ÙÙØªÙØ ÙÙØ§ Ù
ÙØ¹Ø§Ù
Ù Ø§ÙØªÙØ²ÙØ¹ `â...â` تÙ
Ø±ÙØ± _اÙÙ
ÙØªØ¹Ø¯ÙÙØ¯_ `âargsâ` ÙØ§Ø¦Ù
ة٠إÙÙ `âcallâ`.
- ÙØ§ ÙÙØ¨Ù `âapplyâ` Ø¥ÙÙØ§ Ù
ÙØ¹Ø§Ù
Ù `âargsâ` _شبÙ٠باÙÙ
صÙÙÙØ§Øª_.
+<<<<<<< HEAD
أ٠أÙÙ ÙØ°ÙÙ Ø§ÙØ§Ø³ØªØ¯Ø¹Ø§Ø¡ÙÙ ÙÙÙÙ
ÙÙØ§Ù بعضÙÙ
ا Ø§ÙØ¨Ø¹Ø¶. Ù٠تÙÙÙØ¹Ùا ÙØµÙÙ Ù
ÙØªØ¹Ø¯ÙÙØ¯ ÙÙØ³ØªØ¹Ù
Ù `âcallâ`Ø ÙÙ٠تÙÙÙØ¹Ùا شبÙÙÙØ§ باÙÙ
صÙÙÙØ§Øª ÙØ³ØªØ¹Ù
Ù `âapplyâ`.
Ø£Ù
ÙØ§ اÙÙØ§Ø¦Ùات اÙÙ
ÙØªØ¹Ø¯ÙÙØ¯Ø© ÙØ§ÙشبÙÙØ© باÙÙ
صÙÙÙØ§Øª (Ù
ث٠اÙÙ
صÙÙÙØ§Øª Ø§ÙØÙÙÙÙØ©)Ø ÙÙÙ
ÙÙÙØ§ ÙØ¸Ø±ÙÙØ§ استعÙ
ا٠أÙÙ Ù
Ù Ø§ÙØ§Ø«ÙÙÙØ Ø¥ÙÙØ§ Ø£ÙÙ `âapplyâ` سÙÙÙ٠أسرع ØºØ§ÙØ¨Ùا إذ Ø£ÙÙ Ù
ÙØ¹Ø¸Ù
Ù
ØØ±ÙÙØ§Øª Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ØªØØ³Ù٠أدائ٠داخÙÙÙØ§ Ø£ÙØ«Ø± Ù
Ù `âcallâ`.
+=======
+...And for objects that are both iterable and array-like, such as a real array, we can use any of them, but `apply` will probably be faster, because most JavaScript engines internally optimize it better.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ¯Ù تÙ
Ø±ÙØ± ÙØ§ÙØ© اÙÙ
ÙØ¹Ø§Ù
ÙØ§Øª (Ù
ع Ø§ÙØ³ÙاÙ) Ù
Ù Ø¯Ø§ÙØ© Ø¥Ù٠أخر٠_بتÙ
Ø±ÙØ± Ø§ÙØ§Ø³ØªØ¯Ø¹Ø§Ø¡_.
diff --git a/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md b/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md
index 403107ca6..4a381c0b4 100644
--- a/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md
+++ b/1-js/06-advanced-functions/10-bind/5-question-use-bind/solution.md
@@ -1,5 +1,5 @@
-The error occurs because `ask` gets functions `loginOk/loginFail` without the object.
+The error occurs because `askPassword` gets functions `loginOk/loginFail` without the object.
When it calls them, they naturally assume `this=undefined`.
diff --git a/1-js/06-advanced-functions/10-bind/article.md b/1-js/06-advanced-functions/10-bind/article.md
index 3d8cd1f25..97112bed8 100644
--- a/1-js/06-advanced-functions/10-bind/article.md
+++ b/1-js/06-advanced-functions/10-bind/article.md
@@ -113,7 +113,11 @@ let funcUser = func.bind(user);
funcUser(); // John
```
+<<<<<<< HEAD
رأÙÙØ§ «اÙÙØ³Ø®Ø© Ø§ÙØ±Ø§Ø¨Ø·Ø©Â» Ù
Ù `âfuncâ`Ø â`âfunc.bind(user)â` بعد ضبط `âthis=userâ`.
+=======
+Here `func.bind(user)` is a "bound variant" of `func`, with fixed `this=user`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
ا Ø£Ù٠اÙÙ
ÙØ¹Ø§Ù
ÙØ§Øª ÙÙÙÙØ§ تÙÙ
Ø±ÙØ± Ø¥ÙÙ Ø¯Ø§ÙØ© `âfuncâ` Ø§ÙØ£ÙصÙÙØ© «ÙÙ
ا ÙÙ». Ù
ثاÙ:
@@ -170,8 +174,13 @@ let user = {
let say = user.say.bind(user);
+<<<<<<< HEAD
say("Hello"); // â«Hello, John!â (Ù
ÙØ±Ùر اÙÙ
ÙØ¹Ø§Ù
Ù "Hello" Ø¥ÙÙ say)
say("Bye"); // â«Bye, John!â (Ù
ÙØ±Ùر اÙÙ
عاÙ
Ù "Bye" Ø¥ÙÙ say)
+=======
+say("Hello"); // Hello, John! ("Hello" argument is passed to say)
+say("Bye"); // Bye, John! ("Bye" is passed to say)
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
**ØªØ§Ø¨ÙØ¹ Ù
ÙÙØ¯: `âbindAllâ`**
@@ -185,8 +194,12 @@ for (let key in user) {
}
```
+<<<<<<< HEAD
JavaScript libraries also provide functions for convenient mass binding , e.g. [\_.bindAll(object, methodNames)](http://lodash.com/docs#bindAll) in lodash.
+=======
+JavaScript libraries also provide functions for convenient mass binding , e.g. [_.bindAll(object, methodNames)](https://lodash.com/docs#bindAll) in lodash.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
````
## Ø§ÙØ¯ÙØ§Ù Ø§ÙØ¬Ø²Ø¦ÙØ©
diff --git a/1-js/07-object-properties/01-property-descriptors/article.md b/1-js/07-object-properties/01-property-descriptors/article.md
index 57f71f3cc..977abbc45 100644
--- a/1-js/07-object-properties/01-property-descriptors/article.md
+++ b/1-js/07-object-properties/01-property-descriptors/article.md
@@ -20,7 +20,11 @@
Ø§ÙØ·Ø±ÙÙØ© [Object.getOwnPropertyDescriptor](mdn:js/Object/getOwnPropertyDescriptor) تسÙ
Ø Ø¨Ø§ÙØ¥Ø³ØªØ¹ÙاÙ
_اÙÙØ§Ù
Ù_ ع٠اÙÙ
عÙÙÙ
ات Ø§ÙØ®Ø§ØµØ© بأÙÙ Ø®Ø§ØµÙØ©.
+<<<<<<< HEAD
Ù ØµÙØ§ØºØªÙا تÙÙÙ ÙØ§ÙآتÙ:
+=======
+The method [Object.getOwnPropertyDescriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor) allows to query the *full* information about a property.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);
@@ -54,7 +58,11 @@ alert(JSON.stringify(descriptor, null, 2));
*/
```
+<<<<<<< HEAD
ÙØªØºÙÙØ± Ø§ÙØ±Ø§Ùات, ÙÙ
ÙÙÙØ§ إستخداÙ
[Object.defineProperty](mdn:js/Object/defineProperty).
+=======
+To change the flags, we can use [Object.defineProperty](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù ØµÙØ§ØºØªÙا تÙÙÙ ÙØ§ÙآتÙ:
@@ -122,7 +130,13 @@ user.name = "Pete"; // خطأ: ÙØ§ ÙÙ
ÙÙ Ø¥Ø³ÙØ§Ø¯ اÙÙÙÙ
Ø¥ÙÙ Ø§ÙØ®
Ø§ÙØ¢Ù ÙØ³ØªØÙ٠عÙ٠أÙ٠شخص تعدÙ٠اسÙ
ÙØ°Ø§ اÙÙ
ستخدÙ
, Ø¥ÙØ§ Ø¹ÙØ¯ تطبÙÙ `defineProperty` ÙØªØ¹Ø¯ÙÙ Ù
ا ÙØ¹ÙÙØ§Ù ÙØÙ.
+<<<<<<< HEAD
```smart header="ÙØ§ ØªØ¸ÙØ± Ø§ÙØ£Ø®Ø·Ø§Ø¡ Ø¥ÙÙØ§ Ù٠اÙÙØ¶Ø¹ Ø§ÙØµØ§Ø±Ù
`strict mode`" Ù٠اÙÙØ¶Ø¹ Ø§ÙØºÙر صارÙ
`non-strict mode`, ÙØ§ ÙØØ¯Ø« أخطاء Ø¹ÙØ¯ Ø§ÙØªØ¹Ø¯Ù٠عÙÙ Ø®Ø§ØµÙØ© ØºÙØ± ÙØ§Ø¨ÙØ© ÙÙØªØ¹Ø¯ÙÙ. Ù ÙÙÙ Ø§ÙØ¹Ù
ÙÙÙ Ù٠تتÙ
Ø¨ÙØ¬Ø§Ø Ø£ÙØ¶Ø§Ù. أخطاء Ø®Ø±Ù Ø§ÙØ±Ø§ÙÙ ÙØªÙ
تجاÙÙÙØ§ بصÙ
ت Ù٠اÙÙØ¶Ø¹ Ø§ÙØºÙر صارÙ
`non-strict`.
+=======
+```smart header="Errors appear only in strict mode"
+In non-strict mode, no errors occur when writing to non-writable properties and such. But the operation still won't succeed. Flag-violating actions are just silently ignored in non-strict.
+```
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
````
@@ -194,7 +208,11 @@ alert(Object.keys(user)); // name
Ø±Ø§ÙØ© عدÙ
Ø§ÙØ¶Ø¨Ø· (`configurable:false`) اØÙØ§ÙØ§Ù ÙØªÙ
Ø¥Ø¹Ø¯Ø§Ø¯ÙØ§ Ù
Ø³Ø¨ÙØ§Ù Ù٠بعض اÙÙØ§Ø¦Ùات ÙØ§Ùخصائص اÙÙ
ضÙ
ÙÙØ© Ù٠اÙÙØºØ©.
+<<<<<<< HEAD
Ø§ÙØ®Ø§ØµÙØ© Ø§ÙØºÙر ÙØ§Ø¨ÙØ© ÙÙØ¥ØØµØ§Ø¡ ÙØ§ ÙÙ
ÙÙ ØØ°ÙÙØ§.
+=======
+A non-configurable property can't be deleted, its attributes can't be modified.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
Ø«ÙØ§Ù, `Math.PI` ØºÙØ± ÙØ§Ø¨ÙØ© ÙÙØªØ¹Ø¯ÙÙ, ØºÙØ± ÙØ§Ø¨ÙØ© ÙÙØ¥ØØµØ§Ø¡ Ù ØºÙØ± ÙØ§Ø¨ÙØ© ÙØ¥Ø¹Ø§Ø¯Ø© Ø§ÙØ¶Ø¨Ø·:
@@ -215,11 +233,16 @@ alert(JSON.stringify(descriptor, null, 2));
ÙØ°Ø§, ÙÙ ÙØ³ØªØ·Ùع اÙÙ
برÙ
ج تغÙÙØ± ÙÙÙ
Ø© `Math.PI` Ø£Ù Ø§ÙØªØ¹Ø¯Ù٠عÙÙÙØ§.
```js run
+<<<<<<< HEAD
Math.PI = 3; // خطأ
+=======
+Math.PI = 3; // Error, because it has writable: false
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
// delete Math.PI Ù٠تعÙ
Ù Ø£ÙØ¶Ùا
```
+<<<<<<< HEAD
Ø¥Ù ØªÙØ¹Ù٠خاصÙÙØ© Ù
ÙØ¹ ÙØ§Ø¨ÙÙØ© إعادة Ø§ÙØ¶Ø¨Ø· ÙÙ ÙØ±Ø§Ø± ÙØ§ Ø¹ÙØ¯Ø© ÙÙÙ. ÙÙØ§ ÙÙ
ÙÙÙØ§ تغÙÙØ± Ø§ÙØ±Ø§ÙØ© (Ø¥ØªØ§ØØ© ÙØ§Ø¨ÙÙØ© إعادة Ø§ÙØ¶Ø¨Ø·) باستعÙ
ا٠`defineProperty`.
ÙÙÙØ¯ÙÙØ© ÙÙØ°Ø§ اÙÙ
ÙØ¹ ÙØ¶Ø¹ تÙÙÙØ¯Ø§Øª أخر٠عÙÙ `defineProperty`:
@@ -230,6 +253,20 @@ Math.PI = 3; // خطأ
4. Ù
ÙØ¹ تغÙÙØ± ضابط ÙØ¬Ø§Ùب ÙØ§ØµÙ اÙÙØµÙÙ `get/set` (ÙÙÙÙ ÙÙ
ÙÙ Ø¥Ø³ÙØ§Ø¯ ÙÙÙ
Ø¥ÙÙÙ).
**The idea of "configurable: false" is to prevent changes of property flags and its deletion, while allowing to change its value.**
+=======
+We also can't change `Math.PI` to be `writable` again:
+
+```js run
+// Error, because of configurable: false
+Object.defineProperty(Math, "PI", { writable: true });
+```
+
+There's absolutely nothing we can do with `Math.PI`.
+
+Making a property non-configurable is a one-way road. We cannot change it back with `defineProperty`.
+
+**Please note: `configurable: false` prevents changes of property flags and its deletion, while allowing to change its value.**
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Here `user.name` is non-configurable, but we can still change it (as it's writable):
@@ -246,7 +283,7 @@ user.name = 'Pete'; // works fine
delete user.name; // Error
```
-And here we make `user.name` a "forever sealed" constant:
+And here we make `user.name` a "forever sealed" constant, just like the built-in `Math.PI`:
```js run
let user = {
@@ -265,9 +302,21 @@ delete user.name;
Object.defineProperty(user, 'name', { value: 'Pete' });
```
+<<<<<<< HEAD
## Object.defineProperties
ÙÙØ¬Ø¯ طرÙÙØ© [Object.defineProperties(obj, descriptors)](mdn:js/Object/defineProperties) Ù Ø§ÙØªÙ تسÙ
Ø Ø¨ØªØ¹Ø±ÙÙ ÙØ«Ùر Ù
Ù Ø§ÙØ®ØµØ§Ø¦Øµ Ù
Ø±Ù ÙØ§ØØ¯Ù.
+=======
+```smart header="The only attribute change possible: writable true -> false"
+There's a minor exception about changing flags.
+
+We can change `writable: true` to `false` for a non-configurable property, thus preventing its value modification (to add another layer of protection). Not the other way around though.
+```
+
+## Object.defineProperties
+
+There's a method [Object.defineProperties(obj, descriptors)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties) that allows to define many properties at once.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù ØµÙØ§ØºØªÙا تÙÙÙ ÙØ§ÙآتÙ:
@@ -293,7 +342,11 @@ Object.defineProperties(user, {
## Object.getOwnPropertyDescriptors
+<<<<<<< HEAD
ÙØ¬Ùب ÙÙÙ ÙØ§ØµÙات Ø§ÙØ®ØµØ§Ø¦Øµ Ù
Ø¹ÙØ§, ÙÙ
ÙÙÙØ§ إستعÙ
Ø§Ù Ø§ÙØ·Ø±ÙÙØ© [Object.getOwnPropertyDescriptors(obj)](mdn:js/Object/getOwnPropertyDescriptors).
+=======
+To get all property descriptors at once, we can use the method [Object.getOwnPropertyDescriptors(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
بدÙ
ج٠Ù
ع `Object.defineProperties` ÙÙ
Ù٠إستخداÙ
ÙØ§ ÙÙØ³Ø® اÙÙØ§Ø¦Ùات "ÙÙØÙ Ø¹Ù٠عÙÙ
Ù Ø¨Ø±Ø§ÙØ§ØªÙا":
@@ -311,7 +364,11 @@ for (let key in user) {
...Ù ÙÙÙ ÙØ°Ø§ ÙØ§ ÙÙØ³Ø® Ø§ÙØ±Ø§Ùات. ÙØ°Ø§ إذا ÙÙØ§ ÙØ±Ùد ÙØ³Ø® "Ø£ÙØ¶Ù" سÙÙÙ٠إستخداÙ
`Object.defineProperties` Ø£ÙØ¶Ù.
+<<<<<<< HEAD
Ø¥Ø®ØªÙØ§Ù آخر ٠ذÙ٠أ٠`for..in` تتجاÙÙ Ø§ÙØ®ØµØ§Ø¦Øµ Ø§ÙØ±Ù
Ø²ÙØ© (Symbolic Properties), Ù ÙÙÙ `Object.getOwnPropertyDescriptors` ØªÙØ¹Ùد _ÙÙ_ ÙØ§ØµÙÙØ§Øª Ø§ÙØ®ØµØ§Ø¦Øµ بÙ
ا ÙÙÙØ§ Ø§ÙØ±Ù
Ø²ÙØ©.
+=======
+Another difference is that `for..in` ignores symbolic and non-enumerable properties, but `Object.getOwnPropertyDescriptors` returns *all* property descriptors including symbolic and non-enumerable ones.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## Ø¥ØºÙØ§Ù اÙÙØ§Ø¦Ùات عÙ٠اÙÙ
ستÙÙ Ø§ÙØ¹Ø§Ù
@@ -319,6 +376,7 @@ for (let key in user) {
ÙÙØ¬Ø¯ Ø§ÙØ¶Ø§Ù ØªØØ¯Ø¯ Ø§ÙØ¯Ø®Ù٠اÙ٠اÙÙØ§Ø¦Ù _ÙÙÙ_ :
+<<<<<<< HEAD
[Object.preventExtensions(obj)](mdn:js/Object/preventExtensions)
: ÙÙ
ÙØ¹ Ø¥Ø¶Ø§ÙØ© خصائص Ø¬Ø¯ÙØ¯Ø© Ø¥Ù٠اÙÙØ§Ø¦Ù.
@@ -327,9 +385,20 @@ for (let key in user) {
[Object.freeze(obj)](mdn:js/Object/freeze)
: ÙÙ
ÙØ¹ Ø¥Ø¶Ø§ÙØ© Ø§ÙØ®ØµØ§Ø¦Øµ Ø£Ù Ø¥Ø²Ø§ÙØªÙا أ٠تغÙÙØ±Ùا. ÙÙÙÙ
Ø¨ÙØ¶Ø¹ `configurable: false, writable: false` ÙÙÙ Ø§ÙØ®ØµØ§Ø¦Øµ اÙÙ
ÙØ¬Ùدة.
+=======
+[Object.preventExtensions(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions)
+: Forbids the addition of new properties to the object.
+
+[Object.seal(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal)
+: Forbids adding/removing of properties. Sets `configurable: false` for all existing properties.
+
+[Object.freeze(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze)
+: Forbids adding/removing/changing of properties. Sets `configurable: false, writable: false` for all existing properties.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
ا Ø£ÙÙ ÙÙØ§Ù ØªÙØ§Ø¨Ùع Ø£Ø®Ø±Ù ØªÙØØµ تÙ٠اÙÙ
Ø²Ø§ÙØ§:
+<<<<<<< HEAD
[Object.isExtensible(obj)](mdn:js/Object/isExtensible)
: ÙÙØ¹Ùد `false` ÙÙ ÙØ§Ù Ù
Ù
ÙÙØ¹Ùا Ø¥Ø¶Ø§ÙØ© Ø§ÙØ®ØµØ§Ø¦Øµ, ØºÙØ± ذÙÙ `true`.
@@ -338,5 +407,15 @@ for (let key in user) {
[Object.isFrozen(obj)](mdn:js/Object/isFrozen)
: ÙÙØ¹Ùد `true` إذا ÙØ§Ù Ø¥Ø¶Ø§ÙØ©/ØØ°Ù/تعدÙÙ Ø§ÙØ®ØµØ§Ø¦Øµ Ù
Ù
ÙÙØ¹Ø§Ù, Ù ÙÙ Ø§ÙØ®ØµØ§Ø¦Øµ Ø§ÙØØ§ÙÙØ© `configurable: false, writable: false`.
+=======
+[Object.isExtensible(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible)
+: Returns `false` if adding properties is forbidden, otherwise `true`.
+
+[Object.isSealed(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed)
+: Returns `true` if adding/removing properties is forbidden, and all existing properties have `configurable: false`.
+
+[Object.isFrozen(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen)
+: Returns `true` if adding/removing/changing properties is forbidden, and all current properties are `configurable: false, writable: false`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø£Ù
ÙØ§ عÙ٠أرض اÙÙØ§ÙØ¹Ø ÙÙØ§Ø¯Ø±Ùا Ù
ا ÙØ³ØªØ¹Ù
٠تÙÙ Ø§ÙØ·Ø±Ù.
diff --git a/1-js/07-object-properties/02-property-accessors/article.md b/1-js/07-object-properties/02-property-accessors/article.md
index fde204b06..d4610efe6 100644
--- a/1-js/07-object-properties/02-property-accessors/article.md
+++ b/1-js/07-object-properties/02-property-accessors/article.md
@@ -6,7 +6,15 @@
## Ø§ÙØ¬Ø§Ùبات ÙØ§Ùضابطات
+<<<<<<< HEAD
خصائص اÙÙØµÙ٠تÙ
ث٠ب٠"getter" Ù "setter". ÙØ´Ø§Ø± Ø¥ÙÙÙÙ
داخ٠اÙÙØ§Ø¦Ù ب٠`get` and `set`:
+=======
+The second type of property is something new. It's an *accessor property*. They are essentially functions that execute on getting and setting a value, but look like regular properties to an external code.
+
+## Getters and setters
+
+Accessor properties are represented by "getter" and "setter" methods. In an object literal they are denoted by `get` and `set`:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
let obj = {
diff --git a/1-js/08-prototypes/01-prototype-inheritance/article.md b/1-js/08-prototypes/01-prototype-inheritance/article.md
index 0db392e7f..9e8b5f2e4 100644
--- a/1-js/08-prototypes/01-prototype-inheritance/article.md
+++ b/1-js/08-prototypes/01-prototype-inheritance/article.md
@@ -10,7 +10,7 @@ _اÙÙØ±Ø§Ø«Ø© اÙÙÙ
ÙØ°Ø¬ÙØ©_ (ØªØ¯Ø¹Ù Ø£ÙØ¶Ùا اÙÙØ±Ø§Ø«Ø© عبر
ÙÙØ§Ø¦Ùات Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت Ø®Ø§ØµÙØ© Ù
Ø®ÙÙØ© أخر٠باسÙ
`[[Prototype]]` (ÙØ°Ø§ اسÙ
ÙØ§ Ù٠اÙÙ
ÙØ§ØµÙات اÙÙÙØ§Ø³ÙØ© ÙÙØºØ© Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت)Ø ÙÙ٠إÙ
ÙØ§ أ٠تÙÙÙ `null` Ø£Ù Ø£Ù ØªØ´ÙØ± Ø¥ÙÙ ÙØ§Ø¦Ù آخر. ÙØ³Ù
ÙÙ ÙØ°Ø§ اÙÙØ§Ø¦Ù بÙÙâprototypeâ (ÙÙ
ÙØ°Ø¬ Ø£ÙÙÙ).
-When we read a property from `object`, and it's missing, JavaScript automatically takes it from the prototype. In programming, such thing is called "prototypal inheritance". And soon we'll study many examples of such inheritance, as well as cooler language features built upon it.
+When we read a property from `object`, and it's missing, JavaScript automatically takes it from the prototype. In programming, this is called "prototypal inheritance". And soon we'll study many examples of such inheritance, as well as cooler language features built upon it.
Ø¥Ù ÙØ§Ø¦Ù اÙÙÙ
ÙØ°Ø¬ Ø§ÙØ£ÙÙÙ âØ³ØØ±ÙÙâ Ø¥Ù صØÙ اÙÙÙÙØ ÙØÙÙ ÙØ±Ùد ÙØ±Ø§Ø¡Ø© Ø®Ø§ØµÙØ© Ù
Ù ÙØ§Ø¦Ù `object` ÙÙØ§ ÙØ¬Ø¯Ùا Ù
ØØ±ÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±ÙØ¨ØªØ ÙØ£Ø®Ø°Ùا تÙÙØ§Ø¦ÙÙØ§ Ù
Ù ÙØ§Ø¦Ù اÙÙÙ
ÙØ°Ø¬ Ø§ÙØ£ÙÙÙ ÙØ°Ø§Ù اÙÙØ§Ø¦Ù. ÙÙØ³Ù
ÙÙ ÙØ°Ø§ Ù٠عÙÙ
Ø§ÙØ¨Ø±Ù
جة âØ¨Ø§ÙÙØ±Ø§Ø«Ø© اÙÙÙ
ÙØ°Ø¬ÙØ©â (âPrototypal inheritance)Ø ÙÙÙØ§Ù Ø§ÙØ¹Ø¯Ùد Ù
٠اÙÙ
Ø²Ø§ÙØ§ Ø§ÙØ±Ø§Ø¦Ø¹Ø© Ù٠اÙÙØºØ© ÙÙÙ Ø§ÙØªÙÙÙØ§Øª Ø§ÙØ¨Ø±Ù
Ø¬ÙØ© Ù
بÙÙØ© عÙÙÙØ§.
@@ -52,7 +52,11 @@ alert( rabbit.eats ); // true (**)
alert( rabbit.jumps ); // true
```
+<<<<<<< HEAD
ÙÙØ§ ÙØ¶Ø¨Ø· (ÙÙ Ø§ÙØ³Ø·Ø± `(*)`) ÙØ§Ø¦Ù `animal` ÙÙÙÙ٠اÙÙÙ
ÙØ°Ø¬ Ø§ÙØ£ÙÙÙ (Prototype) ÙÙÙØ§Ø¦Ù `rabbit`.
+=======
+Here the line `(*)` sets `animal` to be the prototype of `rabbit`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¨Ø¹Ø¯ÙØ§ Ù
ت٠Ù
ا ØØ§ÙÙØª Ø§ÙØªØ¹ÙÙÙ
Ø© `alert` ÙØ±Ø§Ø¡Ø© Ø§ÙØ®Ø§ØµÙØ© `rabbit.eats` (Ø§ÙØ¸Ø± `(**)`)Ø ÙÙÙ
ÙØ¬Ø¯Ùا ÙÙ ÙØ§Ø¦Ù `rabbit` ستتبع ÙØºØ© Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت Ø§ÙØ®Ø§ØµÙØ© `[[Prototype]]` ÙÙ
Ø¹Ø±ÙØ© Ù
ا ÙÙ ÙØ§Ø¦Ù اÙÙÙ
ÙØ°Ø¬ Ø§ÙØ£ÙÙÙ ÙÙØ§Ø¦Ù `rabbit`Ø ÙØ³ÙØ¬Ø¯Ù ÙØ§Ø¦Ù `animal` (Ø§ÙØ¨ØØ« Ù
٠أسÙ٠إÙ٠أعÙÙ):
@@ -126,7 +130,13 @@ There are only two limitations:
ÙÙ
٠اÙÙØ§Ø¶Ø جÙÙÙØ§ Ø£ÙØ¶Ùا Ø£Ù ÙØ§Ø¦Ù Ø³ÙØ±Ø« ÙØ§Ø¦Ù `[[Prototype]]` ÙØ§ØØ¯ ÙÙØ§ØØ¯ ÙÙØ·Ø ÙØ§ ÙÙ
ÙÙ ÙÙÙØ§Ø¦Ù ÙØ±Ø§Ø«Ø© ÙØ§Ø¦ÙÙÙ.
+<<<<<<< HEAD
```smart header="`**proto**`is a historical getter/setter for`[[Prototype]]`"
+=======
+Also it may be obvious, but still: there can be only one `[[Prototype]]`. An object may not inherit from two others.
+
+```smart header="`__proto__` is a historical getter/setter for `[[Prototype]]`"
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
It's a common mistake of novice developers not to know the difference between these two.
Please note that `__proto__` is _not the same_ as the internal `[[Prototype]]` property. It's a getter/setter for `[[Prototype]]`. Later we'll see situations where it matters, for now let's just keep it in mind, as we build our understanding of JavaScript language.
@@ -281,7 +291,11 @@ for(let prop in rabbit) alert(prop); // jumps, then eats
*/!*
```
+<<<<<<< HEAD
ÙÙ ÙÙ
تÙÙ ÙØ°Ù اÙÙØªÙجة Ù
ا ÙØ±Ùد (Ø£Ù ÙØ±Ùد Ø§Ø³ØªØ«ÙØ§Ø¡ Ø§ÙØ®Ø§ØµÙات اÙÙ
ÙØ±Ùثة)Ø ÙÙÙ
Ù٠استعÙ
Ø§Ù Ø§ÙØªØ§Ø¨Ùع [obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty) اÙÙ
ضÙ
ÙÙ Ù٠اÙÙØºØ©: إذ ÙÙØ¹Ùد `true` ÙÙ ÙØ§Ù ÙÙÙØ§Ø¦Ù `obj` ÙÙØ³Ù (ÙÙÙØ³ ÙÙÙ
ÙØ±ÙØ« Ù
ÙÙ) Ø®Ø§ØµÙØ© Ø¨Ø§ÙØ§Ø³Ù
`key`.
+=======
+If that's not what we want, and we'd like to exclude inherited properties, there's a built-in method [obj.hasOwnProperty(key)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty): it returns `true` if `obj` has its own (not inherited) property named `key`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¨ÙØ°Ø§ ÙÙ
ÙÙÙØ§ ØªØ±Ø´ÙØ Ø§ÙØ®Ø§ØµÙات اÙÙ
ÙØ±Ùثة (ÙÙØªØ¹Ø§Ù
Ù Ù
Ø¹ÙØ§ عÙÙ ØØ¯Ø©):
diff --git a/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md b/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md
index 0073e252e..372d50dd6 100644
--- a/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md
+++ b/1-js/08-prototypes/02-function-prototype/4-new-object-same-constructor/solution.md
@@ -38,7 +38,12 @@ Why `user2.name` is `undefined`?
Here's how `new user.constructor('Pete')` works:
1. First, it looks for `constructor` in `user`. Nothing.
-2. Then it follows the prototype chain. The prototype of `user` is `User.prototype`, and it also has nothing.
-3. The value of `User.prototype` is a plain object `{}`, its prototype is `Object.prototype`. And there is `Object.prototype.constructor == Object`. So it is used.
+2. Then it follows the prototype chain. The prototype of `user` is `User.prototype`, and it also has no `constructor` (because we "forgot" to set it right!).
+3. Going further up the chain, `User.prototype` is a plain object, its prototype is the built-in `Object.prototype`.
+4. Finally, for the built-in `Object.prototype`, there's a built-in `Object.prototype.constructor == Object`. So it is used.
-At the end, we have `let user2 = new Object('Pete')`. The built-in `Object` constructor ignores arguments, it always creates an empty object, similar to `let user2 = {}`, that's what we have in `user2` after all.
+Finally, at the end, we have `let user2 = new Object('Pete')`.
+
+Probably, that's not what we want. We'd like to create `new User`, not `new Object`. That's the outcome of the missing `constructor`.
+
+(Just in case you're curious, the `new Object(...)` call converts its argument to an object. That's a theoretical thing, in practice no one calls `new Object` with a value, and generally we don't use `new Object` to make objects at all).
\ No newline at end of file
diff --git a/1-js/08-prototypes/03-native-prototypes/article.md b/1-js/08-prototypes/03-native-prototypes/article.md
index b3949a9be..b64f59497 100644
--- a/1-js/08-prototypes/03-native-prototypes/article.md
+++ b/1-js/08-prototypes/03-native-prototypes/article.md
@@ -2,7 +2,11 @@
Ø¥Ù Ø§ÙØ®Ø§ØµÙØ© `"prototype"` Ù
ستخدÙ
Ø© بشÙÙ ÙØ§Ø³Ø¹ Ù
Ù Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙÙØ³ÙØ§Ø ØÙØ« Ø£Ù ÙÙ Ø§ÙØ¯ÙØ§Ù Ø§ÙØ¨Ø§ÙÙØ© (constructor functions) تستخدÙ
ÙØ§.
+<<<<<<< HEAD
Ø£ÙÙÙØ§ Ø³ÙØ±Ù Ø§ÙØªÙاصÙÙØ Ø«Ù
ÙØªØ¹ÙÙ
ÙÙÙ ÙØ³ØªØ®Ø¯Ù
ÙØ§ ÙØ¥Ø¶Ø§ÙØ© Ø¥Ù
ÙØ§ÙÙØ§Øª Ø¬Ø¯ÙØ¯Ø© ÙÙÙØ§Ø¦Ùات اÙÙ
ÙØ¬Ùدة باÙÙØ¹Ù (built-in objects).
+=======
+First we'll look at the details, and then how to use it for adding new capabilities to built-in objects.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## Object.prototype
diff --git a/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md b/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md
index 950b4151e..f46aa3f8a 100644
--- a/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md
+++ b/1-js/08-prototypes/04-prototype-methods/2-dictionary-tostring/solution.md
@@ -28,4 +28,8 @@ alert(dictionary); // "apple,__proto__"
Ø¹ÙØ¯ Ø¥ÙØ´Ø§Ø¡ Ø®Ø§ØµÙØ© Ø¨ÙØ§ØµÙ ÙØ¥Ù Ù
ÙØ¹Ø±ÙÙÙØ§ØªÙا تÙÙÙ ÙÙÙ
ÙØ§ `false`. ÙÙØ°ÙÙ Ù٠اÙÙÙØ¯ Ø£Ø¹ÙØ§Ù ÙØ¥Ù `dictionary.toString` ÙÙ ØºÙØ± Ù
Ø¹Ø¯ÙØ¯Ø© (non-enumerable).
+<<<<<<< HEAD
Ø£ÙØ¸Ø± ÙØµÙ [](info:property-descriptors) ÙÙÙ
راجعة.
+=======
+See the chapter [](info:property-descriptors) for review.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/08-prototypes/04-prototype-methods/article.md b/1-js/08-prototypes/04-prototype-methods/article.md
index 82871b94e..dd94fd28e 100644
--- a/1-js/08-prototypes/04-prototype-methods/article.md
+++ b/1-js/08-prototypes/04-prototype-methods/article.md
@@ -4,16 +4,27 @@
تعتبر Ø§ÙØ®Ø§ØµÙØ© `__proto__` ÙØ¯ÙÙ
Ø© ÙØºÙر Ù
دعÙÙ
Ø© (Ù٠عÙ
Ù Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت Ù٠اÙÙ
ØªØµÙØØ§Øª ÙÙØ·).
+<<<<<<< HEAD
Ø§ÙØ¯ÙØ§Ù Ø§ÙØØ¯ÙØ«Ø© ÙÙ:
+=======
+Setting or reading the prototype with `obj.__proto__` is considered outdated and somewhat deprecated (moved to the so-called "Annex B" of the JavaScript standard, meant for browsers only).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
-The modern methods are:
+The modern methods to get/set a prototype are:
-- [Object.create(proto, [descriptors])](mdn:js/Object/create) -- creates an empty object with given `proto` as `[[Prototype]]` and optional property descriptors.
- [Object.getPrototypeOf(obj)](mdn:js/Object/getPrototypeOf) -- returns the `[[Prototype]]` of `obj`.
- [Object.getPrototypeOf(obj)](mdn:js/Object/getPrototypeOf) -- تÙÙÙ
بإرجاع Ø§ÙØ®Ø§ØµÙØ© `[[Prototype]]` Ù
٠اÙÙØ§Ø¦Ù `obj`.
- [Object.setPrototypeOf(obj, proto)](mdn:js/Object/setPrototypeOf) -- ØªØ¬Ø¹Ù Ø§ÙØ®Ø§ØµÙØ© `[[Prototype]]` Ù
٠اÙÙØ§Ø¦Ù `obj` ØªØ´ÙØ± Ø¥ÙÙ `proto`.
+<<<<<<< HEAD
ÙÙØ°Ù Ø§ÙØ¯ÙØ§Ù ÙØ¬Ø¨ استخداÙ
ÙØ§ بÙÙØ§ Ù
Ù `__proto__`.
+=======
+The only usage of `__proto__`, that's not frowned upon, is as a property when creating a new object: `{ __proto__: ... }`.
+
+Although, there's a special method for this too:
+
+- [Object.create(proto[, descriptors])](mdn:js/Object/create) -- creates an empty object with given `proto` as `[[Prototype]]` and optional property descriptors.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¹Ù ÙØ³Ø¨Ù٠اÙÙ
ثاÙ:
@@ -24,7 +35,7 @@ let animal = {
// تÙÙÙ
Ø¨Ø¥ÙØ´Ø§Ø¡ ÙØ§Ù Ø¬Ø¯ÙØ¯ ØÙØ« أ٠اÙÙØ§Ø¦Ù animal ÙÙ
ÙØ°Ø¬ ÙÙ
*!*
-let rabbit = Object.create(animal);
+let rabbit = Object.create(animal); // same as {__proto__: animal}
*/!*
alert(rabbit.eats); // true
@@ -38,7 +49,13 @@ Object.setPrototypeOf(rabbit, {}); // تغÙÙØ± ÙÙ
ÙØ°Ø¬ اÙÙØ§Ø¦Ù rabbit
*/!*
```
+<<<<<<< HEAD
ØªØ³ØªÙØ¨Ù Ø§ÙØ¯Ø§ÙØ© `Object.create` Ù
ØªØºÙØ±Ùا إضاÙÙÙØ§ بشÙÙ Ø§Ø®ØªÙØ§Ø±Ù ÙÙÙ ÙØ§ØµÙ Ø§ÙØ®Ø§ØµÙØ© (property descriptors) ØÙØ« ÙÙ
ÙÙÙØ§ Ø¥Ø¶Ø§ÙØ© خصائص إضاÙÙØ© ÙÙÙØ§Ø¦Ù Ø§ÙØ¬Ø¯Ùد ÙØ§ÙآتÙ:
+=======
+The `Object.create` method is a bit more powerful, as it has an optional second argument: property descriptors.
+
+We can provide additional properties to the new object there, like this:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
let animal = {
@@ -59,20 +76,34 @@ alert(rabbit.jumps); // true
ÙÙ
ÙÙÙØ§ استخداÙ
`Object.create` ÙÙÙÙØ§Ù
Ø¨ÙØ³Ø® ÙØ§Ø¦Ù بشÙÙ Ø£ÙØ¶Ù Ù
Ù ÙØ³Ø® Ø§ÙØ®ØµØ§Ø¦Øµ باستخداÙ
Ø§ÙØªÙرار `for..in`:
```js
+<<<<<<< HEAD
// ÙØ§Ø¦Ù Ø¬Ø¯ÙØ¯ Ù
Ù
اث٠تÙ
اÙ
ÙØ§
let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
+=======
+let clone = Object.create(
+ Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj)
+);
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
ÙØ°Ø§ Ø§ÙØ¥Ø³ØªØ¯Ø¹Ø§Ø¡ ÙÙÙÙ
Ø¨Ø¥ÙØ´Ø§Ø¡ ÙØ³Ø®Ù Ø·Ø¨Ù Ø§ÙØ£ØµÙ Ù
٠اÙÙØ§Ø¦Ù `obj` بÙ
ا ÙÙÙ Ù
٠خصائص Ø³ÙØ§Ø¡Ùا ÙØ§Ùت Ù
Ø¹Ø¯ÙØ¯Ø© (enumerable) Ø£Ù
ÙØ§ ÙÙØ°ÙÙ Ø§ÙØ¬Ø§Ùبات ÙØ§ÙÙ
ØºÙØ±Ø§Øª (getters & setters) -- ÙÙ Ø´ÙØ¦ ÙØ¨Ø§ÙØ®Ø§ØµÙØ© `[[Prototype]]` Ø§ÙØµØÙØØ©.
+<<<<<<< HEAD
## ÙØ¨Ø°Ø© Ù
Ù Ø§ÙØªØ§Ø±ÙØ®
إذا Ø¹Ø¯Ø¯ÙØ§ ÙÙ Ø§ÙØ·Ø±Ù ÙÙØªØÙÙ
ÙÙ `[[Prototype]]`Ø ÙÙÙØ§Ù اÙÙØ«Ùر! ØªÙØ¬Ø¯ اÙÙØ«Ùر Ù
Ù Ø§ÙØ·Ø±Ù ÙÙÙÙØ§Ù
بÙÙØ³ Ø§ÙØ´Ùئ!
ÙÙ
اذاØ
+=======
+
+## Brief history
+
+There're so many ways to manage `[[Prototype]]`. How did that happen? Why?
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ°Ø§ ÙØ£Ø³Ø¨Ø§Ø¨ ØªØ§Ø±ÙØ®ÙØ© Ù
تأصÙÙØ©.
+<<<<<<< HEAD
- Ø®Ø§ØµÙØ© اÙ`"prototype"` ÙØ¯Ø§ÙØ© باÙÙØ© (constructor function) Ù
ÙØ¬Ùدة Ù
٠زÙ
Ø§Ù Ø¨Ø¹ÙØ¯.
- ÙØ§ØÙÙØ§ Ù٠عاÙ
2012 Ø¸ÙØ±Øª Ø§ÙØ¯Ø§ÙØ© `Object.create`. ØÙØ« تÙ
ÙÙÙÙ Ù
Ù Ø¥ÙØ´Ø§Ø¡ ÙØ§Ø¦Ùات بÙÙ
ÙØ°Ø¬ Ù
ÙØ¹Ø·Ù ÙÙÙÙ ÙØ§ ØªØ¹Ø·Ù Ø§ÙØ¥Ù
ÙØ§ÙÙØ© ÙØ¬Ùب أ٠تعدÙÙ Ø§ÙØ®ØµØ§Ø¦ØµØ ÙÙØ°ÙÙ ÙØ§Ù
ت اÙÙ
ØªØµÙØØ§Øª Ø¨Ø¥Ø¶Ø§ÙØ© Ø§ÙØ®Ø§ØµÙØ© `__proto__` Ø§ÙØºÙر Ù
ÙØ«ÙØ© Ù٠اÙÙ
صدر ÙØ§Ùت٠تسÙ
Ø ÙÙÙ
ستخدÙ
Ø£Ù ÙØ¬Ùب Ø£Ù ÙØ¹Ø¯Ù اÙÙÙ
ÙØ°Ø¬ Ù٠أ٠ÙÙØª.
- ÙØ§ØÙÙØ§ Ù٠عاÙ
2015 Ø¸ÙØ±Øª Ø§ÙØ¯Ø§ÙتÙÙ `Object.setPrototypeOf` Ù `Object.getPrototypeOf` ÙÙÙÙØ§Ù
بÙÙØ³ ÙØ¸ÙÙØ© Ø§ÙØ®Ø§ØµÙØ© `__proto__` ÙØÙØ« Ø£Ù Ø§ÙØ®Ø§ØµÙØ© `__proto__` Ù
ÙØ¬Ùدة ÙÙ ÙÙ Ù
ÙØ§Ù ØªÙØ±ÙØ¨ÙØ§ ÙÙØ¯ Ø£ØµØ¨ØØª ÙØ¯ÙÙ
Ø© ÙØ£ØµØ¨ØØª Ù٠طرÙÙÙØ§ Ø¥ÙÙ (Annex B) Ù
٠اÙÙ
صدر ÙØ¨Ø§ÙتاÙÙ Ø£ØµØ¨ØØª Ø§Ø®ØªÙØ§Ø±ÙØ© ÙØ¨Ùئة Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ØºÙØ± اÙÙ
ØªØµÙØØ§Øª.
@@ -80,6 +111,22 @@ let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescr
ÙØ§ÙØ¢Ù Ø£ØµØ¨Ø Ù٠تصرÙÙØ§ ÙÙ ÙØ°Ù Ø§ÙØ·Ø±Ù.
ÙÙ
اذا تÙ
Ø§Ø³ØªØ¨Ø¯Ø§Ù Ø§ÙØ®Ø§ØµÙØ© `__proto__` Ø¨Ø§ÙØ¯Ùا٠`getPrototypeOf/setPrototypeOf`Ø ÙØ°Ø§ سؤا٠Ù
ÙÙ
ÙÙØ³ØªØ¯Ø¹ÙÙØ§ Ø£Ù ÙÙÙÙ
ÙÙ
اذا تعد Ø§ÙØ®Ø§ØµÙØ© `__proto__` Ø³ÙØ¦Ø©. Ø£ÙÙ
٠اÙÙØ±Ø§Ø¡Ø© ÙØªØØµÙ عÙÙ Ø§ÙØ¥Ø¬Ø§Ø¨Ø©.
+=======
+The prototypal inheritance was in the language since its dawn, but the ways to manage it evolved over time.
+
+- The `prototype` property of a constructor function has worked since very ancient times. It's the oldest way to create objects with a given prototype.
+- Later, in the year 2012, `Object.create` appeared in the standard. It gave the ability to create objects with a given prototype, but did not provide the ability to get/set it. Some browsers implemented the non-standard `__proto__` accessor that allowed the user to get/set a prototype at any time, to give more flexibility to developers.
+- Later, in the year 2015, `Object.setPrototypeOf` and `Object.getPrototypeOf` were added to the standard, to perform the same functionality as `__proto__`. As `__proto__` was de-facto implemented everywhere, it was kind-of deprecated and made its way to the Annex B of the standard, that is: optional for non-browser environments.
+- Later, in the year 2022, it was officially allowed to use `__proto__` in object literals `{...}` (moved out of Annex B), but not as a getter/setter `obj.__proto__` (still in Annex B).
+
+Why was `__proto__` replaced by the functions `getPrototypeOf/setPrototypeOf`?
+
+Why was `__proto__` partially rehabilitated and its usage allowed in `{...}`, but not as a getter/setter?
+
+That's an interesting question, requiring us to understand why `__proto__` is bad.
+
+And soon we'll get the answer.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```warn header="ÙØ§ ØªØºÙØ± Ø§ÙØ®Ø§ØµÙØ© `[[Prototype]]`ÙÙ ÙØ§Ø¦Ù Ù
ÙØ¬Ùد إذا ÙØ§Ùت Ø§ÙØ³Ø±Ø¹Ø© تÙÙ
Ù" عÙ
ÙÙÙØ§ ÙÙ
ÙÙÙØ§ Ø£Ù ÙØ¬Ùب Ø£Ù ÙØ¹Ø¯ÙÙ Ø§ÙØ®Ø§ØµÙØ©`[[Prototype]]`Ù٠أ٠ÙÙØªØ ÙÙÙ٠عادة Ù
ا ÙØ¶Ø¹ ÙÙÙØ§ ÙÙÙ
Ø© ÙÙØ· Ø¹ÙØ¯ Ø¥ÙØ´Ø§Ø¡ اÙÙØ§Ø¦Ù ÙÙØ§ ÙØ¹Ø¯ÙÙØ§ بعد ذÙÙ: ÙØ±Ø« اÙÙØ§Ø¦Ù`rabbit`Ù
٠اÙÙØ§Ø¦Ù`animal` ÙÙØ°Ø§ ÙÙ ÙØªØºÙر.
@@ -104,25 +151,58 @@ obj[key] = "some value";
alert(obj[key]); // [object Object], ÙÙÙØ³Øª "some value"!
````
+<<<<<<< HEAD
ÙÙØ§ إذا ÙØ§Ù
اÙÙ
ستخدÙ
Ø¨ÙØªØ§Ø¨Ø© `__proto__`Ø ÙØ¥Ù Ù
Ø§ÙØªØ¨Ù Ø³ÙØªÙ
تجاÙÙÙ!
ÙØ°Ø§ ÙØ§ ÙØ¬Ø¨ Ø£Ù ÙÙØ§Ø¬Ø¦ÙØ§Ø ÙØ§ÙØ®Ø§ØµÙØ© `__proto__` ÙÙØ§ تعاÙ
٠خاص: ÙØ£ÙÙØ§ ÙØ¬Ø¨ أ٠تÙÙÙ ÙØ§Ø¦ÙÙØ§ Ø£Ù `null`Ø ÙÙØ§ ÙÙ
Ù٠أ٠ÙÙÙ٠اÙÙØµ ÙÙ
ÙØ°Ø¬Ùا.
+=======
+Here, if the user types in `__proto__`, the assignment in line 4 is ignored!
+
+That could surely be surprising for a non-developer, but pretty understandable for us. The `__proto__` property is special: it must be either an object or `null`. A string can not become a prototype. That's why assigning a string to `__proto__` is ignored.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙÙÙÙØ§ ÙÙ
ÙÙØµØ¯ Ø£Ù ÙÙØ¹Ù ذÙÙØ Ø£ÙÙØ³ ÙØ°ÙÙØ ÙØ±Ùد Ø£Ù ÙØ®Ø²Ù Ø®Ø§ØµÙØ© بÙÙÙ
ØªÙØ§ ÙØ§Ø³Ù
Ø§ÙØ®Ø§ØµÙØ© `"__proto__"` ÙÙ
ÙØªÙ
ØÙظÙ. ÙÙØ°Ø§ إذ٠خÙÙ!
+<<<<<<< HEAD
Ø§ÙØ¢Ø«Ø§Ø± ÙÙØ§ ÙÙØ³Øª ÙØ§Ø±Ø«ÙØ©Ø ÙÙÙÙ ÙÙ ØØ§Ùات أخر٠ÙÙ
ÙÙ Ø£Ù ÙØ¶Ø¹ Ø®Ø§ØµÙØ© بÙÙÙ
ØªÙØ§ Ø«Ù
ÙØªØºÙر اÙÙÙ
ÙØ°Ø¬ باÙÙØ¹Ù. ÙÙØªÙجة ÙØ°ÙÙ Ø³ÙØ¹Ø·Ù Ø§ÙØªÙÙÙØ° ÙØªØ§Ø¦Ø¬ ØºÙØ± صØÙØØ© ÙØºÙر Ù
تÙÙØ¹Ø©.
+=======
+Here the consequences are not terrible. But in other cases we may be storing objects instead of strings in `obj`, and then the prototype will indeed be changed. As a result, the execution will go wrong in totally unexpected ways.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ£Ø³ÙØ£ Ù
٠ذÙÙ -- ÙØ§ ÙÙÙØ± اÙÙ
Ø·ÙØ±Ù٠عادة ع٠إÙ
ÙØ§ÙÙØ© ÙÙØ°Ù Ø£Ø¨Ø¯ÙØ§. ÙÙØ°Ø§ ÙØ¬Ø¹Ù Ø§ÙØ®Ø·Ø£ صعب اÙÙ
ÙØ§ØØ¸Ø© ÙÙÙ
ÙÙ Ø£Ù ÙØªØÙ٠إÙ٠ثغرة Ø®ØµÙØµÙا إذا ÙØ§Ù Ø§ÙØ¨Ø±ÙاÙ
ج ÙØ¹Ù
٠عÙÙ Ø§ÙØ³ÙØ±ÙØ±.
+<<<<<<< HEAD
ÙÙÙ
ÙÙ Ø£Ù ØªØØ¯Ø« Ø£ÙØ¶Ùا Ø£Ø´ÙØ§Ø¡ ØºÙØ± Ù
تÙÙØ¹Ø© Ø¹ÙØ¯ ÙØ¶Ø¹ ÙÙÙ
Ø© ÙÙØ¯Ø§ÙØ© `toString` ÙØ§Ùت٠ÙÙ Ø¯Ø§ÙØ© Ø¨Ø·Ø¨ÙØ¹ØªÙا ÙÙØ°ÙÙ ÙØ¯Ùا٠أخرÙ.
+=======
+Unexpected things also may happen when assigning to `obj.toString`, as it's a built-in object method.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙÙ ÙÙ
ÙÙÙØ§ ØªØ¬ÙØ¨ ÙØ°Ù اÙÙ
Ø´ÙÙØ©Ø
+<<<<<<< HEAD
Ø£ÙÙÙØ§Ø ÙÙ
ÙÙÙØ§ Ø£Ù ÙØªØÙÙÙ ÙØ§Ø³ØªØ®Ø¯Ø§Ù
اÙÙ`Map` ÙÙØªØ®Ø²Ù٠بدÙÙØ§ Ù
٠اÙÙØ§Ø¦Ùات Ø§ÙØ¹Ø§Ø¯ÙØ© ÙØ³ÙÙÙÙ ÙÙ Ø´ÙØ¦ Ø¨Ø®ÙØ±.
ÙÙÙÙ ÙÙ
ÙÙ ÙÙÙ `Object` Ø£Ù ÙØ®Ø¯Ù
ÙØ§ بشÙÙ Ø¬ÙØ¯ ÙÙØ§Ø ÙØ£Ù صÙÙØ§Ø¹ اÙÙØºØ© Ø£Ø¹Ø·Ù Ø§ÙØªÙ
اÙ
ÙØ§ ÙÙØ°Ù اÙÙ
Ø´ÙÙØ© Ù
Ù ÙÙØª Ø·ÙÙÙ.
Ø¥Ù Ø§ÙØ®Ø§ØµÙØ© `__proto__` ÙÙØ³Øª Ø¨Ø®Ø§ØµÙØ© Ø¹Ø§Ø¯ÙØ© ÙØ¥ÙÙ
ا Ù
ÙØµÙÙ ÙÙØ®Ø§ØµÙØ© `Object.prototype`:
+=======
+First, we can just switch to using `Map` for storage instead of plain objects, then everything's fine:
+
+```js run
+let map = new Map();
+
+let key = prompt("What's the key?", "__proto__");
+map.set(key, "some value");
+
+alert(map.get(key)); // "some value" (as intended)
+```
+
+...But `Object` syntax is often more appealing, as it's more concise.
+
+Fortunately, we *can* use objects, because language creators gave thought to that problem long ago.
+
+As we know, `__proto__` is not a property of an object, but an accessor property of `Object.prototype`:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11

@@ -135,6 +215,7 @@ alert(obj[key]); // [object Object], ÙÙÙØ³Øª "some value"!
```js run
*!*
let obj = Object.create(null);
+// or: obj = { __proto__: null }
*/!*
let key = prompt("What's the key?", "__proto__");
@@ -175,22 +256,35 @@ alert(Object.keys(chineseDictionary)); // hello,bye
## اÙÙ
ÙØ®Øµ
+<<<<<<< HEAD
Ø§ÙØ¯ÙØ§Ù Ø§ÙØØ¯ÙØ«Ø© ÙØ¥Ùشاء ÙÙ
ÙØ°Ø¬ ٠اÙÙØµÙ٠إÙÙÙ ÙÙ:
+=======
+- To create an object with the given prototype, use:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
-- [Object.create(proto, [descriptors])](mdn:js/Object/create) -- creates an empty object with a given `proto` as `[[Prototype]]` (can be `null`) and optional property descriptors.
-- [Object.getPrototypeOf(obj)](mdn:js/Object/getPrototypeOf) -- returns the `[[Prototype]]` of `obj` (same as `__proto__` getter).
-- [Object.setPrototypeOf(obj, proto)](mdn:js/Object/setPrototypeOf) -- sets the `[[Prototype]]` of `obj` to `proto` (same as `__proto__` setter).
+ - literal syntax: `{ __proto__: ... }`, allows to specify multiple properties
+ - or [Object.create(proto[, descriptors])](mdn:js/Object/create), allows to specify property descriptors.
+<<<<<<< HEAD
Ù `__proto__` اÙÙ
ÙØ¬Ùدة باÙÙØ¹Ù ÙØ§Ùت٠تÙÙÙ
Ø¨Ø¬ÙØ¨ أ٠تعدÙÙ Ø§ÙØ®ØµØ§Ø¦Øµ ÙÙØ³Øª Ø¢Ù
ÙØ© ÙÙØ¥Ø³ØªØ®Ø¯Ø§Ù
إذا ÙÙØ§ ÙØ±Ùد Ø£Ù ÙÙØ´Ø¦ خصائص بأسÙ
اء ÙØ¹Ø·ÙÙØ§ اÙÙ
ستخدÙ
ÙÙÙØ§Ø¦Ù ÙØ°ÙÙ ÙØ£Ù اÙÙ
ستخدÙ
ÙÙ
Ù٠أ٠ÙÙØ¯Ø®Ù اسÙ
Ø§ÙØ®Ø§ØµÙØ© ÙÙ `"__proto__"` ÙØ³ÙÙÙÙ ÙÙØ§Ù Ø®Ø·Ø£ÙØ§ ÙØ¨Ø¢Ø«Ø§Ø± ÙÙØªØ§Ø¦Ø¬ ØºÙØ± Ù
تÙÙØ¹Ø©.
ÙØ°Ø§ ÙÙ
ÙÙÙØ§ استخداÙ
`Object.create(null)` ÙØ¥Ùشاء ÙØ§Ø¦Ù Ø¹Ø§Ø¯Ù Ø¬Ø¯ÙØ§ "very plain" بدÙÙ `__proto__` أ٠استخداÙ
اÙÙ `Map` ÙÙØ°Ø§.
ÙØ£ÙØ¶ÙØ§Ø ØªØ¹Ø·Ù Ø§ÙØ¯Ø§ÙØ© `Object.create` طرÙÙØ© سÙÙ ÙÙØ³Ø® اÙÙØ§Ø¦Ù بÙ٠اÙÙØ§ØµÙات (descriptors):
+=======
+ The `Object.create` provides an easy way to shallow-copy an object with all descriptors:
-```js
-let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
-```
+ ```js
+ let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
+ ```
+
+- Modern methods to get/set the prototype are:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
+
+ - [Object.getPrototypeOf(obj)](mdn:js/Object/getPrototypeOf) -- returns the `[[Prototype]]` of `obj` (same as `__proto__` getter).
+ - [Object.setPrototypeOf(obj, proto)](mdn:js/Object/setPrototypeOf) -- sets the `[[Prototype]]` of `obj` to `proto` (same as `__proto__` setter).
+<<<<<<< HEAD
ÙÙØ¯ Ø£ÙØ¶ØÙا Ø£ÙØ¶Ùا Ø£Ù `__proto__` ÙÙ Ø¬Ø§ÙØ¨ Ø£Ù Ù
عدÙÙ ÙÙØ®Ø§ØµÙØ© `[[Prototype]]` ÙÙÙØ¬Ø¯ ÙÙ `Object.prototype` Ù
Ø«Ù ØºÙØ±Ù Ù
Ù Ø§ÙØ¯ÙاÙ.
ÙÙÙ
ÙÙÙØ§ Ø£Ù ÙÙØ´Ø¦ ÙØ§Ø¦ÙÙØ§ Ù
Ù ØºÙØ± ÙÙ
ÙØ°Ø¬ باستخداÙ
`Object.create(null)`Ø ÙÙØ°Ù اÙÙØ§Ø¦Ùات تستخدÙ
ÙÙØ§Ø¦Ùات Ø¹Ø§Ø¯ÙØ© "pure dictionaries" ØÙØ« ÙØ§ ØªÙØ¬Ø¯ ÙØ¯ÙÙØ§ Ø£Ù Ù
شاÙ٠إذا ÙØ§Ù
اÙÙ
ستخدÙ
بإدخا٠`"__proto__"` ÙØ¥Ø³Ù
ÙÙØ®Ø§ØµÙØ©.
@@ -205,3 +299,12 @@ let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescr
- [obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty): تÙÙÙ
بإرجاع `true` إذا Ø§ØØªÙ٠اÙÙØ§Ø¦Ù ÙÙÙØ³ ÙÙ
ÙØ°Ø¬Ù عÙÙ Ø®Ø§ØµÙØ© تسÙ
Ù `key`.
ÙÙ Ø§ÙØ¯ÙØ§Ù Ø§ÙØªÙ تÙÙÙ
بإرجاع خصائص اÙÙØ§Ø¦Ù (Ù
ث٠`Object.keys` ÙØºÙØ±ÙØ§) -- تÙÙÙ
بإرجاع Ø§ÙØ®ØµØ§Ø¦Øµ اÙÙ
ÙØ¬Ùدة Ù٠اÙÙØ§Ø¦Ù ÙÙØ· ÙÙÙØ³Øª اÙÙ
ÙØ¬Ùدة ÙÙ ÙÙ
ÙØ°Ø¬Ù (its prototype). ÙØ¥Ø°Ø§ ÙÙØ§ ÙØ±Ùد إرجاع اÙÙ
ÙØ¬Ùدة Ù٠اÙÙÙ
ÙØ°Ø¬ Ø£ÙØ¶Ùا ÙÙÙ
ÙÙÙØ§ استخداÙ
Ø§ÙØªÙرار `for..in`.
+=======
+- Getting/setting the prototype using the built-in `__proto__` getter/setter isn't recommended, it's now in the Annex B of the specification.
+
+- We also covered prototype-less objects, created with `Object.create(null)` or `{__proto__: null}`.
+
+ These objects are used as dictionaries, to store any (possibly user-generated) keys.
+
+ Normally, objects inherit built-in methods and `__proto__` getter/setter from `Object.prototype`, making corresponding keys "occupied" and potentially causing side effects. With `null` prototype, objects are truly empty.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/1-js/09-classes/01-class/article.md b/1-js/09-classes/01-class/article.md
index 19711656e..d6a6dbf45 100644
--- a/1-js/09-classes/01-class/article.md
+++ b/1-js/09-classes/01-class/article.md
@@ -112,7 +112,7 @@ alert(typeof User); // function
alert(User === User.prototype.constructor); // true
// The methods are in User.prototype, e.g:
-alert(User.prototype.sayHi); // alert(this.name);
+alert(User.prototype.sayHi); // the code of the sayHi method
// there are exactly two methods in the prototype
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
@@ -120,7 +120,11 @@ alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
## ÙÙØ³ Ù
جرد Ø³ÙØ± ÙØÙÙ
+<<<<<<< HEAD
Ø£ØÙاÙÙØ§ ÙÙÙ٠اÙÙØ§Ø³ Ø£Ù "class" عبارة ع٠"Ø³ÙØ± ÙØÙÙ" (بÙÙØ© تÙ
تصÙ
ÙÙ
ÙØ§ ÙØªØ³ÙÙÙ ÙØ±Ø§Ø¡Ø© Ø§ÙØ£Ø´Ùاء Ø ÙÙÙÙ ÙØ§ ØªÙØ¯Ù
Ø£Ù Ø´ÙØ¡ Ø¬Ø¯ÙØ¯) Ø ÙØ£ÙÙ ÙÙ
ÙÙÙØ§ Ù٠اÙÙØ§Ùع Ø£Ù ÙØ¹ÙÙ Ø§ÙØ´ÙØ¡ ÙÙØ³Ù بدÙÙ ÙÙÙ
Ø© "class" عÙÙ Ø§ÙØ¥Ø·ÙاÙ:
+=======
+Sometimes people say that `class` is a "syntactic sugar" (syntax that is designed to make things easier to read, but doesn't introduce anything new), because we could actually declare the same thing without using the `class` keyword at all:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
// rewriting class User in pure functions
@@ -146,7 +150,11 @@ user.sayHi();
ÙØ§ تزا٠ÙÙØ§Ù Ø§Ø®ØªÙØ§Ùات Ù
ÙÙ
Ø©.
+<<<<<<< HEAD
1. Ø£ÙÙØ§Ù Ø ÙØªÙ
تصÙÙÙ Ø¯Ø§ÙØ© تÙ
Ø¥ÙØ´Ø§Ø¤Ùا Ø¨ÙØ§Ø³Ø·Ø© "class" Ø¨ÙØ§Ø³Ø·Ø© Ø®Ø§ØµÙØ© داخÙÙØ© خاصة `[[FunctionKind]]:" classConstructor "`. ÙØ°ÙÙ ÙÙÙ ÙÙØ³Øª تÙ
اÙ
ÙØ§ Ù
Ø«Ù Ø¥ÙØ´Ø§Ø¦Ùا ÙØ¯ÙÙÙØ§.
+=======
+1. First, a function created by `class` is labelled by a special internal property `[[IsClassConstructor]]: true`. So it's not entirely the same as creating it manually.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
تÙÙÙ
اÙÙØºØ© Ø¨Ø§ÙØªØÙÙ Ù
Ù ÙØ°Ù Ø§ÙØ®Ø§ØµÙØ© Ù٠أÙ
اÙÙ Ù
تÙÙØ¹Ø©. عÙ٠سبÙ٠اÙÙ
Ø«Ø§Ù Ø Ø¹ÙÙ Ø¹ÙØ³ اÙÙØ¸ÙÙØ© Ø§ÙØ¹Ø§Ø¯ÙØ© Ø ÙØ¬Ø¨ Ø£Ù ÙØªÙ
Ø§Ø³ØªØ¯Ø¹Ø§Ø¤ÙØ§ ب٠`new`:
diff --git a/1-js/09-classes/02-class-inheritance/article.md b/1-js/09-classes/02-class-inheritance/article.md
index 29d26c1fd..59181bb14 100644
--- a/1-js/09-classes/02-class-inheritance/article.md
+++ b/1-js/09-classes/02-class-inheritance/article.md
@@ -106,7 +106,11 @@ class Rabbit extends Animal {
}
```
+<<<<<<< HEAD
عادة ÙØ§ ÙØ±Ùد استبدا٠طرÙÙØ© Ø±Ø¦ÙØ³ÙØ© تÙ
اÙ
ÙØ§ Ø ÙÙÙÙ Ø¨Ø¯ÙØ§Ù Ù
٠ذÙÙ ÙØ¨Ù٠عÙÙÙØ§ ÙØ§Ø³ØªØ¨Ø¯Ø§ÙÙØ§ Ø£Ù ØªÙØ³Ùع ÙØ¸Ø§Ø¦ÙÙØ§. ÙÙØ¹Ù Ø´ÙØ¦Ùا Ù٠طرÙÙØªÙا Ø ÙÙÙ٠استدعاء Ø§ÙØ·Ø±ÙÙØ© Ø§ÙØ£Ù
ÙØ¨Ù / Ø¨Ø¹Ø¯ÙØ§ Ø£Ù ÙÙ Ø§ÙØ¹Ù
ÙÙØ©.
+=======
+Usually, however, we don't want to totally replace a parent method, but rather to build on top of it to tweak or extend its functionality. We do something in our method, but call the parent method before/after it or in the process.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
تÙÙØ± اÙÙØµÙÙ ÙÙÙ
Ø© Ø±Ø¦ÙØ³ÙØ© `` ÙØ§Ø¦ÙØ© '' ÙØ°ÙÙ.
@@ -161,6 +165,11 @@ rabbit.stop(); // White Rabbit stands still. White Rabbit hides!
إذا تÙ
اÙÙØµÙ٠إÙÙÙ Ø ÙÙÙ Ù
Ø£Ø®ÙØ° Ù
٠اÙÙØ¸ÙÙØ© Ø§ÙØ®Ø§Ø±Ø¬ÙØ©. عÙ٠سبÙ٠اÙÙ
ثاÙ:
+<<<<<<< HEAD
+=======
+If accessed, it's taken from the outer function. For instance:
+
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js
class Rabbit extends Animal {
stop() {
@@ -177,9 +186,13 @@ setTimeout(function() { super.stop() }, 1000);
```
````
+<<<<<<< HEAD
## ØªØ¬Ø§ÙØ² constructor
Ù
ع اÙÙ
ÙØ´Ø¦ÙÙ ÙØµØ¨Ø Ø§ÙØ£Ù
ر ØµØ¹Ø¨ÙØ§ بعض Ø§ÙØ´ÙØ¡.
+=======
+## Overriding constructor
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ØØªÙ Ø§ÙØ¢Ù Ø ÙÙ
ÙÙÙ ÙØ¯Ù "Ø§ÙØ£Ø±Ùب" "Ù
ÙÙØ´Ø¦" خاص بÙ.
@@ -315,13 +328,13 @@ new Rabbit(); // animal
*/!*
```
-Here, class `Rabbit` extends `Animal` and overrides `name` field with its own value.
+Here, class `Rabbit` extends `Animal` and overrides the `name` field with its own value.
There's no own constructor in `Rabbit`, so `Animal` constructor is called.
What's interesting is that in both cases: `new Animal()` and `new Rabbit()`, the `alert` in the line `(*)` shows `animal`.
-**In other words, parent constructor always uses its own field value, not the overridden one.**
+**In other words, the parent constructor always uses its own field value, not the overridden one.**
What's odd about it?
@@ -358,10 +371,14 @@ And that's what we naturally expect. When the parent constructor is called in th
...But for class fields it's not so. As said, the parent constructor always uses the parent field.
-Why is there the difference?
+Why is there a difference?
+<<<<<<< HEAD
Well, the reason is in the field initialization order. The class field is initialized:
+=======
+Well, the reason is the field initialization order. The class field is initialized:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
- Before constructor for the base class (that doesn't extend anything),
- Immediately after `super()` for the derived class.
@@ -369,16 +386,20 @@ In our case, `Rabbit` is the derived class. There's no `constructor()` in it. As
So, `new Rabbit()` calls `super()`, thus executing the parent constructor, and (per the rule for derived classes) only after that its class fields are initialized. At the time of the parent constructor execution, there are no `Rabbit` class fields yet, that's why `Animal` fields are used.
-This subtle difference between fields and methods is specific to JavaScript
+This subtle difference between fields and methods is specific to JavaScript.
Luckily, this behavior only reveals itself if an overridden field is used in the parent constructor. Then it may be difficult to understand what's going on, so we're explaining it here.
If it becomes a problem, one can fix it by using methods or getters/setters instead of fields.
+<<<<<<< HEAD
## Super: Ø§ÙØ£Ø¬Ø²Ø§Ø¡ Ø§ÙØ¯Ø§Ø®ÙÙØ© Ø [[HomeObject]]
````warn header="Ù
عÙÙÙ
ات Ù
ØªÙØ¯Ù
Ø©"
إذا ÙÙØª ØªÙØ±Ø£ Ø§ÙØ¨Ø±ÙاÙ
ج Ø§ÙØªØ¹ÙÙÙ
Ù ÙØ£ÙÙ Ù
رة - ÙÙØ¯ ÙØªÙ
ØªØ®Ø·Ù ÙØ°Ø§ اÙÙØ³Ù
.
+=======
+## Super: internals, [[HomeObject]]
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¥ÙÙ ÙØªØ¹ÙÙ Ø¨Ø§ÙØ¢ÙÙØ§Øª Ø§ÙØ¯Ø§Ø®ÙÙØ© اÙÙØ§Ù
ÙØ© ÙØ±Ø§Ø¡ اÙÙ
ÙØ±Ø§Ø« Ù "Ø§ÙØ³Ùبر".
``
diff --git a/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md
index 8109bb549..0a1eefacd 100644
--- a/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md
+++ b/1-js/09-classes/03-static-properties-methods/3-class-extend-object/solution.md
@@ -21,14 +21,22 @@ alert( rabbit.hasOwnProperty('name') ); // true
ÙÙÙ ÙØ°Ø§ ÙÙØ³ ÙÙ Ø´ÙØ¡ بعد.
+<<<<<<< HEAD
ØØªÙ بعد Ø§ÙØ¥ØµÙØ§Ø Ø ÙØ§ ÙØ²Ø§Ù ÙÙØ§Ù Ø§Ø®ØªÙØ§Ù Ù
ÙÙ
ÙÙ "class rabbit ÙÙØ³Ø¹ اÙÙØ§Ø¦Ù" "Ù
ÙØ§Ø¨Ù" class Rabbit ".
+=======
+Even after the fix, there's still an important difference between `"class Rabbit extends Object"` and `class Rabbit`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙ
ا ÙØ¹ÙÙ
Ø ÙØ¥Ù Ø§ÙØµÙغة "اÙÙ
Ù
تدة" تضع ÙÙ
ÙØ°Ø¬Ù٠أÙÙÙÙÙ:
1. بÙÙ "اÙÙÙ
ÙØ°Ø¬" ÙÙØ¸Ø§Ø¦Ù اÙÙ
ÙØ´Ø¦ (ÙÙØ·Ø±Ù).
2. بÙÙ ÙØ¸Ø§Ø¦Ù اÙÙ
ÙØ´Ø¦ Ø£ÙÙØ³ÙÙ
(ÙÙØ£Ø³Ø§ÙÙØ¨ Ø§ÙØ«Ø§Ø¨ØªØ©).
+<<<<<<< HEAD
ÙÙ ØØ§ÙØªÙØ§ Ø ØªØ¹ÙÙ ÙÙÙ
Ø© "Ø£Ø±ÙØ¨ ÙÙ
تد اÙÙØ§Ø¦Ù" Ù
ا ÙÙÙ:
+=======
+In the case of `class Rabbit extends Object` it means:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
class Rabbit extends Object {}
@@ -37,7 +45,11 @@ alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true
alert( Rabbit.__proto__ === Object ); // (2) true
```
+<<<<<<< HEAD
إذ٠ÙÙÙØ± "Ø§ÙØ£Ø±Ùب" Ø§ÙØ¢Ù Ø¥Ù
ÙØ§ÙÙØ© اÙÙØµÙ٠إÙÙ Ø§ÙØ£Ø³Ø§ÙÙØ¨ Ø§ÙØ«Ø§Ø¨ØªØ© ÙÙ "اÙÙØ§Ø¦Ù" عبر "Ø§ÙØ£Ø±Ùب" Ø Ø¹Ù٠اÙÙØÙ Ø§ÙØªØ§ÙÙ:
+=======
+So `Rabbit` now provides access to the static methods of `Object` via `Rabbit`, like this:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
class Rabbit extends Object {}
@@ -67,7 +79,11 @@ alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // Error
ÙØ°Ø§ `Rabbit` ÙØ§ ÙÙÙØ± اÙÙØµÙ٠إÙÙ Ø§ÙØ£Ø³Ø§ÙÙØ¨ Ø§ÙØ«Ø§Ø¨ØªØ© ÙÙ "اÙÙØ§Ø¦Ù" ÙÙ ÙØ°Ù Ø§ÙØØ§ÙØ©.
+<<<<<<< HEAD
باÙÙ
ÙØ§Ø³Ø¨Ø© Ø ÙØØªÙÙ `Function.prototype` عÙÙ Ø·Ø±Ù ÙØ¸ÙÙÙØ©" عاÙ
Ø© "Ø Ù
Ø«Ù` call` Ù` bind` ÙÙ
ا Ø¥Ù٠ذÙÙ. ÙÙÙ Ù
ØªØ§ØØ© Ù٠اÙÙÙØ§ÙØ© ÙÙ ÙÙØªØ§ Ø§ÙØØ§ÙØªÙÙ Ø ÙØ£Ù Ù
ÙÙØ´Ø¦ `Object` اÙÙ
دÙ
ج Ø` Object .__ proto__ = == Function.prototype`.
+=======
+By the way, `Function.prototype` also has "generic" function methods, like `call`, `bind` etc. They are ultimately available in both cases, because for the built-in `Object` constructor, `Object.__proto__ === Function.prototype`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ§ ÙÙ Ø§ÙØµÙرة:
diff --git a/1-js/09-classes/03-static-properties-methods/article.md b/1-js/09-classes/03-static-properties-methods/article.md
index 56d6e483b..1d0034b3d 100644
--- a/1-js/09-classes/03-static-properties-methods/article.md
+++ b/1-js/09-classes/03-static-properties-methods/article.md
@@ -2,7 +2,13 @@
ÙÙ
ا ÙÙ
ÙÙÙØ§ تعÙÙÙ Ø®Ø§ØµÙØ© ÙØ¯Ø§ÙØ© اÙclass Ø°Ø§ØªÙØ§, ÙÙÙØ³ ÙÙ `"prototype"` Ø§ÙØ®Ø§Øµ Ø¨ÙØ§. Ù
Ø«Ù ÙØ°Ù Ø§ÙØ¯Ùا٠تسÙ
٠بÙ*static*.
+<<<<<<< HEAD
Ù٠اÙÙ class, ÙØªÙ
Ø¥ÙØØ§ÙÙÙ
بÙÙÙ
Ø© Ø±Ø¦ÙØ³ÙØ© `static`'' Ø Ù
Ø«Ù ÙØ°Ø§:
+=======
+We can also assign a method to the class as a whole. Such methods are called *static*.
+
+In a class declaration, they are prepended by `static` keyword, like this:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
class User {
@@ -30,9 +36,17 @@ User.staticMethod(); // true
ÙÙÙ
Ø© `this` ÙÙ`User.staticMethod ()`ÙÙ Ù
ÙÙØ´Ø¦ اÙÙØ¦Ø©` اÙÙ
ستخدÙ
` ÙÙØ³Ù (ÙØ§Ø¹Ø¯Ø© "object ÙØ¨Ù اÙÙÙØ·Ø©").
+<<<<<<< HEAD
عادة Ø ÙØªÙ
استخداÙ
Ø§ÙØ£Ø³Ø§ÙÙØ¨ Ø§ÙØ«Ø§Ø¨ØªØ© ÙØªÙÙÙØ° اÙÙØ¸Ø§Ø¦Ù Ø§ÙØªÙ ØªÙØªÙ
٠إÙ٠اÙÙØ¦Ø© Ø ÙÙÙÙ ÙÙØ³ ÙØ£Ù object Ù
عÙÙ Ù
ÙÙØ§.
عÙ٠سبÙ٠اÙÙ
Ø«Ø§Ù Ø ÙØ¯ÙÙØ§ objects `Article` ÙÙØØªØ§Ø¬ Ø¥ÙÙ ÙØ¸ÙÙØ© ÙÙ
ÙØ§Ø±ÙØªÙØ§. Ø§ÙØÙ Ø§ÙØ·Ø¨Ùع٠ÙÙ Ø¥Ø¶Ø§ÙØ© طرÙÙØ© `Article.compare` Ø Ø¹Ù٠اÙÙØÙ Ø§ÙØªØ§ÙÙ:
+=======
+Usually, static methods are used to implement functions that belong to the class as a whole, but not to any particular object of it.
+
+For instance, we have `Article` objects and need a function to compare them.
+
+A natural solution would be to add `Article.compare` static method:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
class Article {
@@ -62,9 +76,17 @@ articles.sort(Article.compare);
alert( articles[0].title ); // CSS
```
+<<<<<<< HEAD
ÙÙØ§ "Article.compare" تÙ٠اÙÙ
ÙØ§Ùات "Ø£Ø¹ÙØ§Ù" Ø ÙÙØ³ÙÙØ© ÙÙ
ÙØ§Ø±ÙØªÙØ§. Ø¥ÙÙØ§ ÙÙØ³Øª Ø¯Ø§ÙØ© ÙÙ `article` Ø ÙÙÙÙ Ø¨Ø¯ÙØ§Ù Ù
٠اÙÙ `class` بأÙÙ
ÙÙ.
Ù
ثا٠آخر ÙÙ Ù
ا ÙØ³Ù
٠طرÙÙØ© "اÙÙ
ØµÙØ¹". تخÙÙ Ø ÙØÙ Ø¨ØØ§Ø¬Ø© Ø¥Ù٠طر٠ÙÙÙÙØ© ÙØ¥Ùشاء Ù
ÙØ§Ù:
+=======
+Here `Article.compare` method stands "above" articles, as a means to compare them. It's not a method of an article, but rather of the whole class.
+
+Another example would be a so-called "factory" method.
+
+Let's say, we need multiple ways to create an article:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
1. Ø¥ÙØ´Ø§Ø¡ Ø¨ÙØ§Ø³Ø·Ø© Ù
عÙÙ
ات Ù
عÙÙØ© (`Ø§ÙØ¹ÙÙØ§Ù` Ø` Ø§ÙØªØ§Ø±ÙØ®` ÙÙ
ا Ø¥Ù٠ذÙÙ).
2. Ø¥ÙØ´Ø§Ø¡ Ù
ÙØ§Ù ÙØ§Ø±Øº Ø¨ØªØ§Ø±ÙØ® اÙÙÙÙ
.
@@ -72,7 +94,11 @@ alert( articles[0].title ); // CSS
ÙÙ
Ù٠تÙÙÙØ° Ø§ÙØ·Ø±ÙÙØ© Ø§ÙØ£ÙÙÙ Ù
Ù ÙØ¨Ù اÙÙ
ÙØ´Ø¦. ÙÙÙØ«Ø§ÙÙ ÙÙ
ÙÙÙØ§ عÙ
٠طرÙÙØ© ثابتة ÙÙÙØ¦Ø©.
+<<<<<<< HEAD
Ù
ث٠`Article.createTodays()` ÙÙØ§:
+=======
+Such as `Article.createTodays()` here:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
class Article {
@@ -100,9 +126,25 @@ alert( article.title ); // Today's digest
```js
// assuming Article is a special class for managing articles
+<<<<<<< HEAD
// static method to remove the article:
Article.remove({ id: 12345 });
+=======
+// static method to remove the article by id:
+Article.remove({id: 12345});
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
+```
+
+````warn header="Static methods aren't available for individual objects"
+Static methods are callable on classes, not on individual objects.
+
+E.g. such code won't work:
+
+```js
+// ...
+article.createTodays(); /// Error: article.createTodays is not a function
```
+````
## Static properties
diff --git a/1-js/09-classes/04-private-protected-properties-methods/article.md b/1-js/09-classes/04-private-protected-properties-methods/article.md
index 223926857..9db786b18 100644
--- a/1-js/09-classes/04-private-protected-properties-methods/article.md
+++ b/1-js/09-classes/04-private-protected-properties-methods/article.md
@@ -113,7 +113,7 @@ class CoffeeMachine {
let coffeeMachine = new CoffeeMachine(100);
// add water
-coffeeMachine.waterAmount = -10; // Error: Negative water
+coffeeMachine.waterAmount = -10; // _waterAmount will become 0, not -10
```
Now the access is under control, so setting the water amount below zero becomes impossible.
@@ -188,7 +188,11 @@ new CoffeeMachine().setWaterAmount(100);
ÙØ¬Ø¨ Ø£Ù ÙØ¨Ø¯Ø£ Ø§ÙØ£Ùراد ب٠`#`. ÙÙ
Ù٠اÙÙØµÙ٠إÙÙÙØ§ ÙÙØ· Ù
٠داخ٠اÙÙØµÙ.
+<<<<<<< HEAD
عÙ٠سبÙ٠اÙÙ
Ø«Ø§Ù Ø Ø¥ÙÙÙ Ø®Ø§ØµÙØ© `# waterLimit` Ø§ÙØ®Ø§ØµØ© ÙØ§ÙطرÙÙØ© Ø§ÙØ®Ø§ØµØ© ÙÙØØµ اÙÙ
ÙØ§Ù` # checkWater`:
+=======
+For instance, here's a private `#waterLimit` property and the water-checking private method `#fixWaterAmount`:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
class CoffeeMachine {
diff --git a/1-js/09-classes/06-instanceof/article.md b/1-js/09-classes/06-instanceof/article.md
index b50c937b7..175f72a2e 100644
--- a/1-js/09-classes/06-instanceof/article.md
+++ b/1-js/09-classes/06-instanceof/article.md
@@ -55,6 +55,7 @@ alert(arr instanceof Object); // ÙØ¹Ù
Ù
ثاÙ:
+<<<<<<< HEAD
```js run
// â«Ø¶Ø¨Ø· instanceOf ÙÙØªØÙÙ Ù
Ù Ø§ÙØ§Ùتراض اÙÙØ§Ø¦Ù
// â«Ø¨Ø£Ù ÙÙ Ø´ÙØ¡ ÙÙ
ÙÙ Ø§ÙØ®Ø§ØµÙØ© canEat ÙÙ ØÙÙØ§Ù
@@ -63,13 +64,27 @@ alert(arr instanceof Object); // ÙØ¹Ù
if (obj.canEat) return true;
}
}
+=======
+ ```js run
+ // set up instanceof check that assumes that
+ // anything with canEat property is an animal
+ class Animal {
+ static [Symbol.hasInstance](obj) {
+ if (obj.canEat) return true;
+ }
+ }
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
let obj = { canEat: true };
alert(obj instanceof Animal); // true: Animal[Symbol.hasInstance](obj) is called
```
+<<<<<<< HEAD
2. ÙÙØ³ ÙØ£ØºÙب Ø§ÙØ£ØµÙØ§Ù Ø§ÙØªØ§Ø¨Ùع `Symbol.hasInstance`. ÙÙ ÙØ°Ù Ø§ÙØØ§ÙØ© تستعÙ
٠اÙÙ
ÙØ·Ù Ø§ÙØ¹Ø§Ø¯Ù: ÙÙØØµ `obj instanceOf Class` ÙÙ ÙØ§Ù ÙØ§Ø¦Ù `Class.prototype` Ù
ساÙÙÙØ§ ÙØ£ØØ¯ ÙØ§Ø¦Ùات prototype ÙÙ Ø³ÙØ³ÙØ© ÙØ§Ø¦Ùات prototype ÙÙÙØ§Ø¦Ù `obj`.
+=======
+2. Most classes do not have `Symbol.hasInstance`. In that case, the standard logic is used: `obj instanceof Class` checks whether `Class.prototype` is equal to one of the prototypes in the `obj` prototype chain.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ¨Ø¹Ø¨Ø§Ø±Ø© Ø£Ø®Ø±Ù Ø ÙØ§Ø²Ù بÙÙÙÙ
ÙØ§ØØ¯Ùا تÙÙ Ø§ÙØ¢Ø®Ø±:
@@ -87,9 +102,17 @@ alert(arr instanceof Object); // ÙØ¹Ù
Ø£Ù
ÙØ§ ÙÙ ÙÙÙØ§ ÙÙ ØØ§ÙØ© ÙØ±Ø§Ø«Ø©Ø ÙØ³ØªØªÙÙÙ٠عÙ
ÙÙØ© اÙÙ
Ø·Ø§Ø¨ÙØ© Ø¹ÙØ¯ Ø§ÙØ®Ø·ÙØ© Ø§ÙØ«Ø§ÙÙØ©:
+<<<<<<< HEAD
```js run
class Animal {}
class Rabbit extends Animal {}
+=======
+ // rabbit.__proto__ === Animal.prototype (no match)
+ *!*
+ // rabbit.__proto__.__proto__ === Animal.prototype (match!)
+ */!*
+ ```
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
let rabbit = new Rabbit();
*!*
diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md
index 3ae2bfba4..cf2cb92ea 100644
--- a/1-js/09-classes/07-mixins/article.md
+++ b/1-js/09-classes/07-mixins/article.md
@@ -103,7 +103,11 @@ new User("Dude").sayHi(); // Ù
Ø±ØØ¨Ø§Ù Dude!
ÙØ°Ø§ بسبب Ø§ÙØ¯Ø§ÙØ© `sayHi` Ù `sayBye` Ø§ÙØ°Ù تÙ
Ø¥ÙØ´Ø§Ø¤ÙÙ
ا ÙÙ `sayHiMixin`. ÙØ°Ø§ عÙÙ Ø§ÙØ±ØºÙ
Ù
٠اÙ٠تÙ
ÙØ³Ø®ÙÙ
, `[[HomeObject]]` Ø§ÙØ®Ø§Øµ بÙÙ
ÙÙ Ù
رجع Ø§ÙØ®Ø§ØµÙØ© Ø§ÙØ¯Ø§Ø®ÙÙØ© `sayHiMixin`, ÙÙ
ا ÙÙ Ù
ÙØ¶Ø ÙÙ Ø§ÙØµÙرة Ø§Ø¹ÙØ§Ù.
+<<<<<<< HEAD
ÙÙ
ا Ø£Ù `super` ÙØ¨ØØ« Ø¹Ù Ø§ÙØ¯Ø§ÙØ© Ø§ÙØ£Ø¨ ÙÙ `[[HomeObject]].[[Prototype]]`, ÙØ°Ø§ ÙØ¹Ù٠اÙÙ ÙØ¨ØØ« ÙÙ `sayHiMixin.[[Prototype]]`, Ù ÙÙØ³ `User.[[Prototype]]`.
+=======
+As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that means it searches `sayHiMixin.[[Prototype]]`.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
## EventMixin
diff --git a/1-js/10-error-handling/1-try-catch/article.md b/1-js/10-error-handling/1-try-catch/article.md
index 1be1a6791..eadb1f9d8 100644
--- a/1-js/10-error-handling/1-try-catch/article.md
+++ b/1-js/10-error-handling/1-try-catch/article.md
@@ -630,7 +630,11 @@ window.onerror = function (message, url, line, col, error) {
Ø¯ÙØ± اÙÙ
Ø¹Ø§ÙØ¬ Ø§ÙØ´Ø§Ù
Ù `window.onerror` ادة ÙØ§ ÙÙÙ٠استرداد تÙÙÙØ° Ø§ÙØ¨Ø±ÙاÙ
ج اÙÙØµÙ - ربÙ
ا ÙÙÙ٠ذÙÙ Ù
ستØÙÙÙØ§ ÙÙ ØØ§ÙØ© ÙØ¬Ùد أخطاء ÙÙ Ø§ÙØ¨Ø±Ù
جة Ø ÙÙÙÙ ÙØ¥Ø±Ø³Ø§Ù Ø±Ø³Ø§ÙØ© Ø§ÙØ®Ø·Ø£ Ø¥Ù٠اÙÙ
Ø·ÙØ±ÙÙ.
+<<<<<<< HEAD
ÙÙØ§Ù Ø£ÙØ¶Ùا خدÙ
ات اÙÙÙØ¨ Ø§ÙØªÙ تÙÙØ± تسجÙÙ Ø§ÙØ£Ø®Ø·Ø§Ø¡ ÙÙ
Ø«Ù ÙØ°Ù Ø§ÙØØ§ÙØ§Øª Ø Ù
ث٠أ٠.
+=======
+There are also web-services that provide error-logging for such cases, like or .
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ¹Ù
ÙÙ٠عÙÙ ÙØ°Ø§ اÙÙØÙ:
diff --git a/1-js/10-error-handling/2-custom-errors/article.md b/1-js/10-error-handling/2-custom-errors/article.md
index ead4734ea..66e453696 100644
--- a/1-js/10-error-handling/2-custom-errors/article.md
+++ b/1-js/10-error-handling/2-custom-errors/article.md
@@ -15,6 +15,7 @@
```
let json = `{ "name": "John", "age": 30 }`;
```
+<<<<<<< HEAD
Ø³ÙØ³ØªØ¹Ù
Ù ÙÙ Ø§ÙØ´ÙÙØ±Ø© Ø§ÙØªØ§Ø¨Ùع `JSON.parse`Ø ÙØ¥Ù استÙÙ
ÙØ§Ø¦Ù `json` Ù
Ø¹Ø·ÙØ¨ رÙ
٠خطأ `SyntaxError`. ÙÙÙÙØ ØØªÙÙ ÙÙ
ÙØ§Ù اÙÙØ§Ø¦Ù صØÙØÙا ØµÙØ§ØºÙÙØ§Ø ÙÙØ§ ÙØ¹ÙÙ ÙØ°Ø§ Ø£Ù٠اÙÙ
ستخدÙ
ØµØ§ÙØÙØ§ Ø£ÙØ¶ÙØ§Ø Ø£Ù
ÙØ§Ø ÙØ±Ø¨ÙÙ
ا ÙØ§ ÙØØªÙ٠بعض Ø§ÙØ¨ÙØ§ÙØ§Øª Ù
Ø«Ù Ø®Ø§ØµÙØªÙ Ø§ÙØ§Ø³Ù
`json` ÙØ§ÙعÙ
ر `name` Ø§ÙØ¶Ø±ÙØ±ÙØªÙÙ ÙÙÙ
ستخدÙ
ÙÙ.
@@ -26,6 +27,19 @@ let json = `{ "name": "John", "age": 30 }`;
ÙÙØ¹Ø±Ù Ù
ا ÙØØ§ÙÙ ØªÙØ³Ø¹ØªÙ:
```
// Ø´ÙÙØ±Ø© Ù
Ø¨Ø³ÙØ·Ø© ÙØµÙÙ Ø§ÙØ®Ø·Ø£ â«Error اÙÙ
ضÙ
ÙÙ ÙÙ ÙØºØ© Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙÙØ³Ùا
+=======
+
+Internally, we'll use `JSON.parse`. If it receives malformed `json`, then it throws `SyntaxError`. But even if `json` is syntactically correct, that doesn't mean that it's a valid user, right? It may miss the necessary data. For instance, it may not have `name` and `age` properties that are essential for our users.
+
+Our function `readUser(json)` will not only read JSON, but check ("validate") the data. If there are no required fields, or the format is wrong, then that's an error. And that's not a `SyntaxError`, because the data is syntactically correct, but another kind of error. We'll call it `ValidationError` and create a class for it. An error of that kind should also carry the information about the offending field.
+
+Our `ValidationError` class should inherit from the `Error` class.
+
+The `Error` class is built-in, but here's its approximate code so we can understand what we're extending:
+
+```js
+// The "pseudocode" for the built-in Error class defined by JavaScript itself
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
class Error {
constructor(message) {
this.message = message;
@@ -35,8 +49,15 @@ this.stack = ; // ÙÙØ³Øª ÙÙØ§Ø³ÙØ©Ø Ø¥ÙÙØ§ Ø£ÙÙ Ø£ØºÙØ¨
}
```
+<<<<<<< HEAD
Ø§ÙØ¢Ù صار ÙÙØª Ø£Ù ÙØ±Ø« Ø§ÙØµÙÙ `ValidationError` Ù
ÙÙØ§:
```
+=======
+Now let's inherit `ValidationError` from it and try it in action:
+
+```js run
+*!*
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
class ValidationError extends Error {
constructor(message) {
super(message); // (1)
@@ -100,6 +121,7 @@ throw err; // خطأ ÙØ§ ÙØ¹Ø±ÙÙØ عÙÙÙØ§ إعادة رÙ
ÙÙ (**)
} else if (err.name == "SyntaxError") { // (*)
// ...
```
+<<<<<<< HEAD
ÙÙÙÙ٠استعÙ
ا٠`instanceof` Ø£ÙØ¶Ù Ø¨ÙØ«Ùر إذ ÙØØ¯Ø« ÙÙÙØ³Ùع Ù
Ø³ØªÙØ¨ÙÙØ§ Ø§ÙØµÙÙ `ValidationError` Ø¨Ø£ØµÙØ§Ù ÙØ±Ø¹ÙØ© Ù
ÙÙ Ù
Ø«Ù
`PropertyRequiredError`Ø ÙØ§ÙÙØØµ عبر `instanceof` Ø³ÙØ¸ÙÙ ÙØ¹Ù
Ù ÙÙØ£ØµÙا٠اÙÙ
ÙØ±Ùثة Ù
ÙÙØ
ÙÙ
ا Ù
٠اÙÙ
ÙÙ
Ù Ø£Ù ØªÙØ¹Ùد ÙØªÙØ© `catch` رÙ
Ù Ø§ÙØ£Ø®Ø·Ø§Ø¡ Ø§ÙØªÙ ÙØ§ تÙÙÙ
ÙØ§Ø ÙÙ
ا ÙÙ Ø§ÙØ³Ø·Ø± `(**)`. ÙÙØ³ عÙÙ ÙØ°Ù اÙÙØªÙØ© Ø¥ÙÙØ§ Ø§ÙØªØ¹Ø§Ù
Ù Ù
ع
@@ -110,6 +132,18 @@ throw err; // خطأ ÙØ§ ÙØ¹Ø±ÙÙØ عÙÙÙØ§ إعادة رÙ
ÙÙ (**)
Ù
ÙØ¬Ùدة Ø£Ù ÙØ§Ù ÙØ³ÙÙØ§ خطأ (Ù
Ø«Ù ØªÙØ¯ÙÙ
Ø³ÙØ³ÙØ© ÙØµÙØ© ÙÙÙ
ة٠ÙÙØ¹Ù
ر `age`). ÙÙØµÙع Ø§ÙØµÙÙ .... `PropertyRequiredError`
ÙÙØ³ØªØ¹Ù
ÙÙ ÙÙØ· ÙÙØ®Ø§ØµÙات ØºÙØ± اÙÙ
ÙØ¬ÙØ¯Ø©Ø ÙØ³ÙØØªÙ٠عÙ٠أÙÙØ© Ù
عÙÙÙ
ات إضاÙÙØ© Ø¹Ù Ø§ÙØ®Ø§ØµÙØ© اÙÙØ§Ùصة.
```
+=======
+
+The `instanceof` version is much better, because in the future we are going to extend `ValidationError`, make subtypes of it, like `PropertyRequiredError`. And `instanceof` check will continue to work for new inheriting classes. So that's future-proof.
+
+Also it's important that if `catch` meets an unknown error, then it rethrows it in the line `(**)`. The `catch` block only knows how to handle validation and syntax errors, other kinds (caused by a typo in the code or other unknown reasons) should fall through.
+
+## Further inheritance
+
+The `ValidationError` class is very generic. Many things may go wrong. The property may be absent or it may be in a wrong format (like a string value for `age` instead of a number). Let's make a more concrete class `PropertyRequiredError`, exactly for absent properties. It will carry additional information about the property that's missing.
+
+```js run
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
class ValidationError extends Error {
constructor(message) {
diff --git a/1-js/11-async/01-callbacks/article.md b/1-js/11-async/01-callbacks/article.md
index 37412d2fb..cffe8f197 100644
--- a/1-js/11-async/01-callbacks/article.md
+++ b/1-js/11-async/01-callbacks/article.md
@@ -28,7 +28,11 @@ function loadScript(src) {
}
```
+<<<<<<< HEAD
ÙØªÙ
Ø¥ÙØØ§Ù Ø§ÙÙ
Ø³ØªÙØ¯ Ø§ÙØ¬Ø¯Ùد Ø Ø§ÙØ°Ù تÙ
Ø¥ÙØ´Ø§Ø¤Ù دÙÙØ§Ù
ÙÙÙÙØ§ Ø Ø§ÙØ¹Ùصر `
```
+<<<<<<< HEAD
ÙÙÙ Ø£Ø±Ø¯ÙØ§ Ø£Ù ÙÙØ´Ø¦ Ù
ØªØºÙØ± عاÙ
عÙÙ Ù
ستÙ٠اÙÙØ§Ùذة ÙÙ
ÙÙÙØ§ تعÙÙÙÙ ØµØ±Ø§ØØ© ÙÙÙ
تغÙÙØ± `window` ÙÙÙ
ÙÙÙØ§ اÙÙØµÙ٠إÙÙÙ ÙÙØ°Ø§ `window.user`. ÙÙÙÙ ÙØ§Ø¨Ø¯ Ù
Ù ÙØ¬Ùد سبب ÙØ¬ÙÙÙ ÙØ°ÙÙ.
+=======
+```smart
+In the browser, we can make a variable window-level global by explicitly assigning it to a `window` property, e.g. `window.user = "John"`.
+
+Then all scripts will see it, both with `type="module"` and without it.
+
+That said, making such global variables is frowned upon. Please try to avoid them.
+```
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
### تÙÙÙÙ
Ø´ÙÙØ±Ø© اÙÙØØ¯Ø© ÙÙ
رة ÙØ§ØØ¯Ø© ÙÙØ·
+<<<<<<< HEAD
ÙÙ Ø§Ø³ØªÙØ±Ø¯ØªÙ ÙÙØ³ اÙÙØØ¯Ø© ÙÙ Ø£ÙØ«Ø± Ù
Ù Ù
ÙØ§ÙØ ÙÙØ§ تÙÙÙÙØ° Ø´ÙÙØ±ØªÙا Ø¥ÙÙØ§ Ù
رة ÙØ§ØØ¯Ø©Ø ÙØ¨Ø¹Ø¯Ùا ØªÙØµØ¯Ùر Ø¥ÙÙ Ù
Ù Ø§Ø³ØªÙØ±Ø¯Ùا.
ÙÙÙØ°Ø§ ØªÙØ§Ø¨Ø¹ Ù
ÙÙ
Ù Ù
Ø¹Ø±ÙØªÙا. ÙÙØ±Ù بعض Ø§ÙØ£Ù
Ø«ÙØ©.
+=======
+If the same module is imported into multiple other modules, its code is executed only once, upon the first import. Then its exports are given to all further importers.
+
+The one-time evaluation has important consequences, that we should be aware of.
+
+Let's see a couple of examples.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø£ÙÙÙØ§Ø ÙÙ ÙØ§Ù ÙØ´ÙÙØ±Ø© اÙÙØØ¯Ø© Ø§ÙØªÙ ستÙÙÙÙØ° Ø£ÙÙ ØªØ£Ø«ÙØ±Ø§Øª (Ù
ث٠عرض Ø±Ø³Ø§ÙØ© Ø£Ù Ù
ا شابÙ)Ø ÙØ§Ø³ØªÙØ±Ø§Ø¯ÙØ§ Ø£ÙØ«Ø± Ù
Ù Ù
Ø±ÙØ© Ø³ÙØ´ØºÙ٠ذÙÙ Ø§ÙØªØ£Ø«Ùر Ù
رة ÙØ§ØØ¯Ø©Ø ÙÙ٠أÙÙ Ù
رة ÙÙØ·:
@@ -134,9 +183,17 @@ import `./alert.js`; // â«ÙÙÙÙØ°Øª Ø´ÙÙØ±Ø© اÙÙØØ¯Ø©!
import `./alert.js`; // (ÙØ§ ÙØ±Ù Ø´ÙØ¦Ùا ÙÙØ§)
```
+<<<<<<< HEAD
Ù٠اÙÙØ§ÙØ¹Ø ÙØ´ÙÙØ±Ø§Øª اÙÙØØ¯Ø§Øª عاÙÙØ© اÙÙ
ستÙÙ Ù٠بÙÙØ© Ø§ÙØ¨Ø±Ù
Ø¬ÙØ© ÙØ§ ØªÙØ³ØªØ¹Ù
٠إÙÙØ§ ÙØªÙ
ÙÙØ¯ بÙÙ Ø§ÙØ¨ÙØ§ÙØ§Øª Ø§ÙØ¯Ø§Ø®ÙÙØ© ÙØ¥ÙØ´Ø§Ø¦ÙØ§. ÙÙÙ Ø£Ø±Ø¯ÙØ§ Ø´ÙØ¦Ùا ÙÙØ¹Ùد استعÙ
اÙÙØ ÙÙØµØ¯Ùر اÙÙØØ¯Ø©.
Ø§ÙØ¢Ù ØØ§Ù ÙÙØª Ù
ثا٠Ù
Ø³ØªÙØ§Ù Ù
ØªÙØ¯ÙÙ
Ø£ÙØ«Ø±.
+=======
+The second import shows nothing, because the module has already been evaluated.
+
+There's a rule: top-level module code should be used for initialization, creation of module-specific internal data structures. If we need to make something callable multiple times - we should export it as a function, like we did with `sayHi` above.
+
+Now, let's consider a deeper example.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙÙ٠بأÙÙ ÙÙØ§Ù ÙØØ¯Ø© ØªÙØµØ¯Ùر ÙØ§Ø¦ÙÙØ§:
@@ -161,6 +218,7 @@ import {admin} from './admin.js';
alert(admin.name); // Pete
*!*
+<<<<<<< HEAD
// â«ÙÙÙØ§ اÙÙ
ÙÙÙÙ â1.js Ù â2.js Ø³ÙØ³ØªÙردا٠ÙÙØ³ اÙÙØ§Ø¦Ù
// â«Ø§ÙتغÙÙØ±Ø§Øª اÙÙØªÙ Ø³ØªØØ¯Ø«Ù Ù٠اÙÙ
ÙÙ â1.js ستÙÙÙ Ù
Ø±Ø¦ÙØ© Ù٠اÙÙ
ÙÙ â2.js
*/!*
@@ -171,24 +229,52 @@ alert(admin.name); // Pete
ÙØªÙØ ÙÙØ§ ÙØ°Ø§ Ø§ÙØ³ÙÙÙ âØ¶Ø¨Ø·â Ø§ÙÙØØ¯Ø© Ø¹ÙØ¯ Ø£ÙÙÙ Ø§Ø³ØªÙØ±Ø§Ø¯ ÙÙØ§Ø ÙÙØ¶Ø¨Ø· Ø®Ø§ØµÙØ§ØªÙا اÙÙ
رة Ø§ÙØ£ÙÙÙØ ÙÙ
ت٠Ù
ا استÙÙØ±Ø¯Øª Ù
رة أخر٠تÙÙÙ Ø¬Ø§ÙØ²Ø©.
ÙÙ
Ø«ÙÙØ§ ÙØ¯ ØªÙØ¯ÙÙ
ÙÙØ§ ÙØØ¯Ø© `admin.js` بعض اÙÙ
Ø²Ø§ÙØ§ ÙÙÙÙ ØªØ·ÙØ¨ أ٠تأت٠اÙ
ØªÙØ§Ø²Ø§Øª Ø§ÙØ¥Ø¯Ø§Ø±Ø© Ù
٠خارج ÙØ§Ø¦Ù `admin` Ø¥Ù٠داخÙÙ:
+=======
+// Both 1.js and 2.js reference the same admin object
+// Changes made in 1.js are visible in 2.js
+*/!*
+```
+
+As you can see, when `1.js` changes the `name` property in the imported `admin`, then `2.js` can see the new `admin.name`.
+
+That's exactly because the module is executed only once. Exports are generated, and then they are shared between importers, so if something changes the `admin` object, other importers will see that.
+
+**Such behavior is actually very convenient, because it allows us to *configure* modules.**
+
+In other words, a module can provide a generic functionality that needs a setup. E.g. authentication needs credentials. Then it can export a configuration object expecting the outer code to assign to it.
+
+Here's the classical pattern:
+1. A module exports some means of configuration, e.g. a configuration object.
+2. On the first import we initialize it, write to its properties. The top-level application script may do that.
+3. Further imports use the module.
+
+For instance, the `admin.js` module may provide certain functionality (e.g. authentication), but expect the credentials to come into the `config` object from outside:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
// ð admin.js
-export let admin = { };
+export let config = { };
export function sayHi() {
- alert(`Ready to serve, ${admin.name}!`);
+ alert(`Ready to serve, ${config.user}!`);
}
```
+<<<<<<< HEAD
ÙØ¶Ø¨Ø· ÙÙ `init.js` (Ø£ÙÙÙ ÙØµ برÙ
Ø¬Ù ÙØªØ·Ø¨ÙÙÙØ§) اÙÙ
ØªØºÙØ± `admin.name`. Ø¨Ø¹Ø¯ÙØ§ Ø³ÙØ±Ø§Ù ÙÙÙ Ù
٠أراد بÙ
ا Ù٠ذÙÙ Ø§ÙØ§Ø³ØªØ¯Ø¹Ø§Ø¡Ø§Øª Ù
Ù Ø¯Ø§Ø®Ù ÙØØ¯Ø© `admin.js` ÙÙØ³Ùا:
+=======
+Here, `admin.js` exports the `config` object (initially empty, but may have default properties too).
+
+Then in `init.js`, the first script of our app, we import `config` from it and set `config.user`:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
// ð init.js
-import {admin} from './admin.js';
-admin.name = "Pete";
+import {config} from './admin.js';
+config.user = "Pete";
```
+<<<<<<< HEAD
ÙÙÙ
ÙÙ ÙÙØØ¯Ø© أخر٠استعÙ
ا٠`admin.name`:
```
@@ -196,20 +282,39 @@ admin.name = "Pete";
import {admin, sayHi} from './admin.js';
alert(admin.name); // *!*Pete*/!*
+=======
+...Now the module `admin.js` is configured.
+
+Further importers can call it, and it correctly shows the current user:
+
+```js
+// ð another.js
+import {sayHi} from './admin.js';
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
sayHi(); // Ready to serve, *!*Pete*/!*!
```
+
### import.meta
ÙØØªÙ٠اÙÙØ§Ø¦Ù `import.meta` عÙÙ Ù
عÙÙÙ
ات اÙÙØØ¯Ø© Ø§ÙØØ§ÙÙØ©.
+<<<<<<< HEAD
ÙÙØ¹ØªÙ
د Ù
ØØªÙØ§ÙØ§ عÙÙ Ø§ÙØ¨Ùئة Ø§ÙØØ§ÙÙØ©Ø ÙÙ٠اÙÙ
تصÙÙØØ§Øª ÙØØªÙ٠عÙ٠عÙÙØ§Ù اÙÙØµ Ø§ÙØ¨Ø±Ù
ج٠أ٠عÙÙØ§Ù ØµÙØØ© اÙÙÙØ¨ Ø§ÙØØ§ÙÙØ© ÙÙ ÙØ§Ù داخ٠HTML:
+=======
+Its content depends on the environment. In the browser, it contains the URL of the script, or a current webpage URL if inside HTML:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
html run height=0
```
@@ -236,7 +341,11 @@ html run height=0
ÙÙ
ا Ø£Ù ÙÙØ§Ù Ø¹Ø¯ÙØ© ÙØ±Ù٠تخص٠اÙÙ
ØªØµÙØØ§Øª Ø§ÙØ³Ùربتات (اÙÙ
عتÙ
دة عÙ٠اÙÙØØ¯Ø§Øª) باÙÙÙØ¹ `type="module"â` Ù
ÙØ§Ø²Ùة٠بتÙÙ Ø§ÙØ¹Ø§Ø¯ÙØ©.
+<<<<<<< HEAD
ÙÙ ÙÙØª ØªÙØ±Ø£ ÙØ°Ø§ اÙÙØµÙ ÙØ£ÙÙ Ù
Ø±Ø©Ø Ø£Ù ÙÙ
تÙ٠تستعÙ
٠اÙÙ
ØØ±ÙÙ Ù٠اÙÙ
تصÙÙØ ÙÙÙ
ÙÙ٠تخطÙÙ ÙØ°Ø§ اÙÙØ³Ù
.
+=======
+You may want to skip this section for now if you're reading for the first time, or if you don't use JavaScript in a browser.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
### Ø³ÙØ±Ø¨ØªØ§Øª اÙÙØØ¯Ø§Øª Ù
Ø¤Ø¬ÙØ©
@@ -244,9 +353,13 @@ html run height=0
Ø£Ù ÙØ¨Ø¹Ø¨Ø§Ø±Ø© أخرÙ:
+<<<<<<< HEAD
- ØªÙØ²ÙÙ Ø§ÙØ³Ùربتات اÙÙ
عتÙ
دة عÙ٠اÙÙØØ¯Ø§Øª Ø§ÙØ®Ø§Ø±Ø¬ÙØ© `â
+
+
+
+ No messages.
+
+
+
+
+
+
+
+
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.js b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.js
new file mode 100644
index 000000000..ea55b4478
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.js
@@ -0,0 +1,24 @@
+const startMessagesBtn = document.querySelector('.start-messages'); // (1)
+const closeWindowBtn = document.querySelector('.window__button'); // (2)
+const windowElementRef = new WeakRef(document.querySelector(".window__body")); // (3)
+
+startMessagesBtn.addEventListener('click', () => { // (4)
+ startMessages(windowElementRef);
+ startMessagesBtn.disabled = true;
+});
+
+closeWindowBtn.addEventListener('click', () => document.querySelector(".window__body").remove()); // (5)
+
+
+const startMessages = (element) => {
+ const timerId = setInterval(() => { // (6)
+ if (element.deref()) { // (7)
+ const payload = document.createElement("p");
+ payload.textContent = `Message: System status OK: ${new Date().toLocaleTimeString()}`;
+ element.deref().append(payload);
+ } else { // (8)
+ alert("The element has been deleted."); // (9)
+ clearInterval(timerId);
+ }
+ }, 1000);
+};
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-01.svg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-01.svg
new file mode 100644
index 000000000..2a507dbcd
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-01.svg
@@ -0,0 +1,32 @@
+
+
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-02.svg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-02.svg
new file mode 100644
index 000000000..6cc199a12
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-02.svg
@@ -0,0 +1,33 @@
+
+
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-03.svg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-03.svg
new file mode 100644
index 000000000..949a14f9f
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-03.svg
@@ -0,0 +1,75 @@
+
+
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-04.svg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-04.svg
new file mode 100644
index 000000000..1177d6580
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-04.svg
@@ -0,0 +1,77 @@
+
+
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-05.svg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-05.svg
new file mode 100644
index 000000000..e738f8e7e
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-05.svg
@@ -0,0 +1,103 @@
+
+
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-01.png b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-01.png
new file mode 100644
index 000000000..fc33a023a
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-01.png differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-02.png b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-02.png
new file mode 100644
index 000000000..7d8bb01e8
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-02.png differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-03.gif b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-03.gif
new file mode 100644
index 000000000..b81966dda
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-03.gif differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-04.jpg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-04.jpg
new file mode 100644
index 000000000..ba60f1e86
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-04.jpg differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-05.gif b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-05.gif
new file mode 100644
index 000000000..d34bda4d7
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-05.gif differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-06.jpg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-06.jpg
new file mode 100644
index 000000000..b2655540f
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-06.jpg differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-07.gif b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-07.gif
new file mode 100644
index 000000000..51f874518
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-07.gif differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-08.jpg b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-08.jpg
new file mode 100644
index 000000000..5f98aec14
Binary files /dev/null and b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry-demo-08.jpg differ
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.css b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.css
new file mode 100644
index 000000000..e6c9e3960
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.css
@@ -0,0 +1,285 @@
+:root {
+ --mineralGreen: 60, 98, 85;
+ --viridianGreen: 97, 135, 110;
+ --swampGreen: 166, 187, 141;
+ --fallGreen: 234, 231, 177;
+ --brinkPink: #FA7070;
+ --silverChalice: 178, 178, 178;
+ --white: 255, 255, 255;
+ --black: 0, 0, 0;
+
+ --topBarHeight: 64px;
+ --itemPadding: 32px;
+ --containerGap: 8px;
+}
+
+@keyframes zoom-in {
+ 0% {
+ transform: scale(1, 1);
+ }
+
+ 100% {
+ transform: scale(1.30, 1.30);
+ }
+}
+
+body, html {
+ margin: 0;
+ padding: 0;
+}
+
+.app {
+ min-height: 100vh;
+ background-color: rgba(var(--viridianGreen), 0.5);
+}
+
+.header {
+ height: var(--topBarHeight);
+ padding: 0 24px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ background-color: rgba(var(--mineralGreen), 1);
+}
+
+.header-text {
+ color: white;
+}
+
+.container {
+ display: flex;
+ gap: 24px;
+ padding: var(--itemPadding);
+}
+
+.item {
+ width: 50%;
+}
+
+.item--scrollable {
+ overflow-y: scroll;
+ height: calc(100vh - var(--topBarHeight) - (var(--itemPadding) * 2));
+}
+
+.thumbnails-container {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ justify-content: center;
+ align-items: center;
+}
+
+.thumbnail-item {
+ width: calc(25% - var(--containerGap));
+ cursor: pointer;
+ position: relative;
+}
+
+.thumbnail-item:hover {
+ z-index: 1;
+ animation: zoom-in 0.1s forwards;
+}
+
+.thumbnail-item--selected {
+ outline: 3px solid rgba(var(--fallGreen), 1);
+ outline-offset: -3px;
+}
+
+.badge {
+ width: 16px;
+ height: 16px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ padding: 4px;
+ position: absolute;
+ right: 8px;
+ bottom: 8px;
+ border-radius: 50%;
+ border: 2px solid rgba(var(--fallGreen), 1);
+ background-color: rgba(var(--swampGreen), 1);
+}
+
+.check {
+ display: inline-block;
+ transform: rotate(45deg);
+ border-bottom: 2px solid white;
+ border-right: 2px solid white;
+ width: 6px;
+ height: 12px;
+}
+
+.img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.actions {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ align-content: center;
+ padding: 0 0 16px 0;
+ gap: 8px;
+}
+
+.select {
+ padding: 16px;
+ cursor: pointer;
+ font-weight: 700;
+ color: rgba(var(--black), 1);
+ border: 2px solid rgba(var(--swampGreen), 0.5);
+ background-color: rgba(var(--swampGreen), 1);
+}
+
+.select:disabled {
+ cursor: not-allowed;
+ background-color: rgba(var(--silverChalice), 1);
+ color: rgba(var(--black), 0.5);
+ border: 2px solid rgba(var(--black), 0.25);
+}
+
+.btn {
+ outline: none;
+ padding: 16px;
+ cursor: pointer;
+ font-weight: 700;
+ color: rgba(var(--black), 1);
+ border: 2px solid rgba(var(--black), 0.5);
+}
+
+.btn--primary {
+ background-color: rgba(var(--mineralGreen), 1);
+}
+
+.btn--primary:hover:not([disabled]) {
+ background-color: rgba(var(--mineralGreen), 0.85);
+}
+
+.btn--secondary {
+ background-color: rgba(var(--viridianGreen), 0.5);
+}
+
+.btn--secondary:hover:not([disabled]) {
+ background-color: rgba(var(--swampGreen), 0.25);
+}
+
+.btn--success {
+ background-color: rgba(var(--fallGreen), 1);
+}
+
+.btn--success:hover:not([disabled]) {
+ background-color: rgba(var(--fallGreen), 0.85);
+}
+
+.btn:disabled {
+ cursor: not-allowed;
+ background-color: rgba(var(--silverChalice), 1);
+ color: rgba(var(--black), 0.5);
+ border: 2px solid rgba(var(--black), 0.25);
+}
+
+.previewContainer {
+ margin-bottom: 16px;
+ display: flex;
+ width: 100%;
+ height: 40vh;
+ overflow: scroll;
+ border: 3px solid rgba(var(--black), 1);
+}
+
+.previewContainer--disabled {
+ background-color: rgba(var(--black), 0.1);
+ cursor: not-allowed;
+}
+
+.canvas {
+ margin: auto;
+ display: none;
+}
+
+.canvas--ready {
+ display: block;
+}
+
+.spinnerContainer {
+ display: flex;
+ gap: 8px;
+ flex-direction: column;
+ align-content: center;
+ align-items: center;
+ margin: auto;
+}
+
+.spinnerContainer--hidden {
+ display: none;
+}
+
+.spinnerText {
+ margin: 0;
+ color: rgba(var(--mineralGreen), 1);
+}
+
+.spinner {
+ display: inline-block;
+ width: 50px;
+ height: 50px;
+ margin: auto;
+ border: 3px solid rgba(var(--mineralGreen), 0.3);
+ border-radius: 50%;
+ border-top-color: rgba(var(--mineralGreen), 0.9);
+ animation: spin 1s ease-in-out infinite;
+}
+
+@keyframes spin {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+.loggerContainer {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ padding: 0 8px 8px 8px;
+ width: 100%;
+ min-height: 30vh;
+ max-height: 30vh;
+ overflow: scroll;
+ border-left: 3px solid rgba(var(--black), 0.25);
+}
+
+.logger-title {
+ display: flex;
+ align-items: center;
+ padding: 8px;
+ position: sticky;
+ height: 40px;
+ min-height: 40px;
+ top: 0;
+ left: 0;
+ background-color: rgba(var(--viridianGreen), 1);
+ font-size: 24px;
+ font-weight: 700;
+ margin: 0;
+}
+
+.logger-item {
+ font-size: 14px;
+ padding: 8px;
+ border: 2px solid #5a5a5a;
+ color: white;
+}
+
+.logger--primary {
+ background-color: #13315a;
+}
+
+.logger--success {
+ background-color: #385a4e;
+}
+
+.logger--error {
+ background-color: #5a1a24;
+}
\ No newline at end of file
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.html b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.html
new file mode 100644
index 000000000..7ce52f927
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
Photo Library Collage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.js b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.js
new file mode 100644
index 000000000..983b34d9a
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/index.js
@@ -0,0 +1,228 @@
+import {
+ createImageFile,
+ loadImage,
+ weakRefCache,
+ LAYOUTS,
+ images,
+ THUMBNAIL_PARAMS,
+ stateObj,
+} from "./utils.js";
+
+export const state = new Proxy(stateObj, {
+ set(target, property, value) {
+ const previousValue = target[property];
+
+ target[property] = value;
+
+ if (previousValue !== value) {
+ handleStateChange(target);
+ }
+
+ return true;
+ },
+});
+
+// Elements.
+const thumbnailsContainerEl = document.querySelector(".thumbnails-container");
+const selectEl = document.querySelector(".select");
+const previewContainerEl = document.querySelector(".previewContainer");
+const canvasEl = document.querySelector(".canvas");
+const createCollageBtn = document.querySelector(".btn-create-collage");
+const startOverBtn = document.querySelector(".btn-start-over");
+const downloadBtn = document.querySelector(".btn-download");
+const spinnerContainerEl = document.querySelector(".spinnerContainer");
+const spinnerTextEl = document.querySelector(".spinnerText");
+const loggerContainerEl = document.querySelector(".loggerContainer");
+
+// Renders.
+// Render thumbnails previews.
+images.forEach((img) => {
+ const thumbnail = document.createElement("div");
+ thumbnail.classList.add("thumbnail-item");
+
+ thumbnail.innerHTML = `
+
+ `;
+
+ thumbnail.addEventListener("click", (e) => handleSelection(e, img));
+
+ thumbnailsContainerEl.appendChild(thumbnail);
+});
+// Render layouts select.
+LAYOUTS.forEach((layout) => {
+ const option = document.createElement("option");
+ option.value = JSON.stringify(layout);
+ option.innerHTML = layout.name;
+ selectEl.appendChild(option);
+});
+
+const handleStateChange = (state) => {
+ if (state.loading) {
+ selectEl.disabled = true;
+ createCollageBtn.disabled = true;
+ startOverBtn.disabled = true;
+ downloadBtn.disabled = true;
+ previewContainerEl.classList.add("previewContainer--disabled");
+ spinnerContainerEl.classList.remove("spinnerContainer--hidden");
+ spinnerTextEl.innerText = "Loading...";
+ canvasEl.classList.remove("canvas--ready");
+ } else if (!state.loading) {
+ selectEl.disabled = false;
+ createCollageBtn.disabled = false;
+ startOverBtn.disabled = false;
+ downloadBtn.disabled = false;
+ previewContainerEl.classList.remove("previewContainer--disabled");
+ spinnerContainerEl.classList.add("spinnerContainer--hidden");
+ canvasEl.classList.add("canvas--ready");
+ }
+
+ if (!state.selectedImages.size) {
+ createCollageBtn.disabled = true;
+ document.querySelectorAll(".badge").forEach((item) => item.remove());
+ } else if (state.selectedImages.size && !state.loading) {
+ createCollageBtn.disabled = false;
+ }
+
+ if (!state.collageRendered) {
+ downloadBtn.disabled = true;
+ } else if (state.collageRendered) {
+ downloadBtn.disabled = false;
+ }
+};
+handleStateChange(state);
+
+const handleSelection = (e, imgName) => {
+ const imgEl = e.currentTarget;
+
+ imgEl.classList.toggle("thumbnail-item--selected");
+
+ if (state.selectedImages.has(imgName)) {
+ state.selectedImages.delete(imgName);
+ state.selectedImages = new Set(state.selectedImages);
+ imgEl.querySelector(".badge")?.remove();
+ } else {
+ state.selectedImages = new Set(state.selectedImages.add(imgName));
+
+ const badge = document.createElement("div");
+ badge.classList.add("badge");
+ badge.innerHTML = `
+
+ `;
+ imgEl.prepend(badge);
+ }
+};
+
+// Make a wrapper function.
+let getCachedImage;
+(async () => {
+ getCachedImage = await weakRefCache(loadImage);
+})();
+
+const calculateGridRows = (blobsLength) =>
+ Math.ceil(blobsLength / state.currentLayout.columns);
+
+const drawCollage = (images) => {
+ state.drawing = true;
+
+ let context = canvasEl.getContext("2d");
+
+ /**
+ * Calculate canvas dimensions based on the current layout.
+ * */
+ context.canvas.width =
+ state.currentLayout.itemWidth * state.currentLayout.columns;
+ context.canvas.height =
+ calculateGridRows(images.length) * state.currentLayout.itemHeight;
+
+ let currentRow = 0;
+ let currentCanvasDx = 0;
+ let currentCanvasDy = 0;
+
+ for (let i = 0; i < images.length; i++) {
+ /**
+ * Get current row of the collage.
+ * */
+ if (i % state.currentLayout.columns === 0) {
+ currentRow += 1;
+ currentCanvasDx = 0;
+
+ if (currentRow > 1) {
+ currentCanvasDy += state.currentLayout.itemHeight;
+ }
+ }
+
+ context.drawImage(
+ images[i],
+ 0,
+ 0,
+ images[i].width,
+ images[i].height,
+ currentCanvasDx,
+ currentCanvasDy,
+ state.currentLayout.itemWidth,
+ state.currentLayout.itemHeight,
+ );
+
+ currentCanvasDx += state.currentLayout.itemWidth;
+ }
+
+ state.drawing = false;
+ state.collageRendered = true;
+};
+
+const createCollage = async () => {
+ state.loading = true;
+
+ const images = [];
+
+ for (const image of state.selectedImages.values()) {
+ const blobImage = await getCachedImage(image.img);
+
+ const url = URL.createObjectURL(blobImage);
+ const img = await createImageFile(url);
+
+ images.push(img);
+ URL.revokeObjectURL(url);
+ }
+
+ state.loading = false;
+
+ drawCollage(images);
+};
+
+/**
+ * Clear all settled data to start over.
+ * */
+const startOver = () => {
+ state.selectedImages = new Set();
+ state.collageRendered = false;
+ const context = canvasEl.getContext("2d");
+ context.clearRect(0, 0, canvasEl.width, canvasEl.height);
+
+ document
+ .querySelectorAll(".thumbnail-item--selected")
+ .forEach((item) => item.classList.remove("thumbnail-item--selected"));
+
+ loggerContainerEl.innerHTML = 'Logger:
';
+};
+
+const downloadCollage = () => {
+ const date = new Date();
+ const fileName = `Collage-${date.getDay()}-${date.getMonth()}-${date.getFullYear()}.png`;
+ const img = canvasEl.toDataURL("image/png");
+ const link = document.createElement("a");
+ link.download = fileName;
+ link.href = img;
+ link.click();
+ link.remove();
+};
+
+const changeLayout = ({ target }) => {
+ state.currentLayout = JSON.parse(target.value);
+};
+
+// Listeners.
+selectEl.addEventListener("change", changeLayout);
+createCollageBtn.addEventListener("click", createCollage);
+startOverBtn.addEventListener("click", startOver);
+downloadBtn.addEventListener("click", downloadCollage);
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/utils.js b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/utils.js
new file mode 100644
index 000000000..f0140c116
--- /dev/null
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/utils.js
@@ -0,0 +1,321 @@
+const loggerContainerEl = document.querySelector(".loggerContainer");
+
+export const images = [
+ {
+ img: "https://images.unsplash.com/photo-1471357674240-e1a485acb3e1",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1589118949245-7d38baf380d6",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1527631746610-bca00a040d60",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1500835556837-99ac94a94552",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1503220317375-aaad61436b1b",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1501785888041-af3ef285b470",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1528543606781-2f6e6857f318",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1523906834658-6e24ef2386f9",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1539635278303-d4002c07eae3",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1533105079780-92b9be482077",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1516483638261-f4dbaf036963",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1502791451862-7bd8c1df43a7",
+ },
+ {
+ img: "https://plus.unsplash.com/premium_photo-1663047367140-91adf819d007",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1506197603052-3cc9c3a201bd",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1517760444937-f6397edcbbcd",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1518684079-3c830dcef090",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1505832018823-50331d70d237",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1524850011238-e3d235c7d4c9",
+ },
+ {
+ img: "https://plus.unsplash.com/premium_photo-1661277758451-b5053309eea1",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1541410965313-d53b3c16ef17",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1528702748617-c64d49f918af",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1502003148287-a82ef80a6abc",
+ },
+ {
+ img: "https://plus.unsplash.com/premium_photo-1661281272544-5204ea3a481a",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1503457574462-bd27054394c1",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1499363536502-87642509e31b",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1551918120-9739cb430c6d",
+ },
+ {
+ img: "https://plus.unsplash.com/premium_photo-1661382219642-43e54f7e81d7",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1497262693247-aa258f96c4f5",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1525254134158-4fd5fdd45793",
+ },
+ {
+ img: "https://plus.unsplash.com/premium_photo-1661274025419-4c54107d5c48",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1553697388-94e804e2f0f6",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1574260031597-bcd9eb192b4f",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1536323760109-ca8c07450053",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1527824404775-dce343118ebc",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1612278675615-7b093b07772d",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1522010675502-c7b3888985f6",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1501555088652-021faa106b9b",
+ },
+ {
+ img: "https://plus.unsplash.com/premium_photo-1669223469435-27e091439169",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1506012787146-f92b2d7d6d96",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1511739001486-6bfe10ce785f",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1553342385-111fd6bc6ab3",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1516546453174-5e1098a4b4af",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1527142879-95b61a0b8226",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1520466809213-7b9a56adcd45",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1516939884455-1445c8652f83",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1545389336-cf090694435e",
+ },
+ {
+ img: "https://plus.unsplash.com/premium_photo-1669223469455-b7b734c838f4",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1454391304352-2bf4678b1a7a",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1433838552652-f9a46b332c40",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1506125840744-167167210587",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1522199873717-bc67b1a5e32b",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1495904786722-d2b5a19a8535",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1614094082869-cd4e4b2905c7",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1474755032398-4b0ed3b2ae5c",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1501554728187-ce583db33af7",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1515859005217-8a1f08870f59",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1531141445733-14c2eb7d4c1f",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1500259783852-0ca9ce8a64dc",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1510662145379-13537db782dc",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1573790387438-4da905039392",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1512757776214-26d36777b513",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1518855706573-84de4022b69b",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1500049242364-5f500807cdd7",
+ },
+ {
+ img: "https://images.unsplash.com/photo-1528759335187-3b683174c86a",
+ },
+];
+export const THUMBNAIL_PARAMS = "w=240&h=240&fit=crop&auto=format";
+
+// Console styles.
+export const CONSOLE_BASE_STYLES = [
+ "font-size: 12px",
+ "padding: 4px",
+ "border: 2px solid #5a5a5a",
+ "color: white",
+].join(";");
+export const CONSOLE_PRIMARY = [
+ CONSOLE_BASE_STYLES,
+ "background-color: #13315a",
+].join(";");
+export const CONSOLE_SUCCESS = [
+ CONSOLE_BASE_STYLES,
+ "background-color: #385a4e",
+].join(";");
+export const CONSOLE_ERROR = [
+ CONSOLE_BASE_STYLES,
+ "background-color: #5a1a24",
+].join(";");
+
+// Layouts.
+export const LAYOUT_4_COLUMNS = {
+ name: "Layout 4 columns",
+ columns: 4,
+ itemWidth: 240,
+ itemHeight: 240,
+};
+export const LAYOUT_8_COLUMNS = {
+ name: "Layout 8 columns",
+ columns: 8,
+ itemWidth: 240,
+ itemHeight: 240,
+};
+export const LAYOUTS = [LAYOUT_4_COLUMNS, LAYOUT_8_COLUMNS];
+
+export const createImageFile = async (src) =>
+ new Promise((resolve, reject) => {
+ const img = new Image();
+ img.src = src;
+ img.onload = () => resolve(img);
+ img.onerror = () => reject(new Error("Failed to construct image."));
+ });
+
+export const loadImage = async (url) => {
+ try {
+ const response = await fetch(url);
+ if (!response.ok) {
+ throw new Error(String(response.status));
+ }
+
+ return await response.blob();
+ } catch (e) {
+ console.log(`%cFETCHED_FAILED: ${e}`, CONSOLE_ERROR);
+ }
+};
+
+export const weakRefCache = (fetchImg) => {
+ const imgCache = new Map();
+ const registry = new FinalizationRegistry(({ imgName, size, type }) => {
+ const cachedImg = imgCache.get(imgName);
+ if (cachedImg && !cachedImg.deref()) {
+ imgCache.delete(imgName);
+ console.log(
+ `%cCLEANED_IMAGE: Url: ${imgName}, Size: ${size}, Type: ${type}`,
+ CONSOLE_ERROR,
+ );
+
+ const logEl = document.createElement("div");
+ logEl.classList.add("logger-item", "logger--error");
+ logEl.innerHTML = `CLEANED_IMAGE: Url: ${imgName}, Size: ${size}, Type: ${type}`;
+ loggerContainerEl.appendChild(logEl);
+ loggerContainerEl.scrollTop = loggerContainerEl.scrollHeight;
+ }
+ });
+
+ return async (imgName) => {
+ const cachedImg = imgCache.get(imgName);
+
+ if (cachedImg?.deref() !== undefined) {
+ console.log(
+ `%cCACHED_IMAGE: Url: ${imgName}, Size: ${cachedImg.size}, Type: ${cachedImg.type}`,
+ CONSOLE_SUCCESS,
+ );
+
+ const logEl = document.createElement("div");
+ logEl.classList.add("logger-item", "logger--success");
+ logEl.innerHTML = `CACHED_IMAGE: Url: ${imgName}, Size: ${cachedImg.size}, Type: ${cachedImg.type}`;
+ loggerContainerEl.appendChild(logEl);
+ loggerContainerEl.scrollTop = loggerContainerEl.scrollHeight;
+
+ return cachedImg?.deref();
+ }
+
+ const newImg = await fetchImg(imgName);
+ console.log(
+ `%cFETCHED_IMAGE: Url: ${imgName}, Size: ${newImg.size}, Type: ${newImg.type}`,
+ CONSOLE_PRIMARY,
+ );
+
+ const logEl = document.createElement("div");
+ logEl.classList.add("logger-item", "logger--primary");
+ logEl.innerHTML = `FETCHED_IMAGE: Url: ${imgName}, Size: ${newImg.size}, Type: ${newImg.type}`;
+ loggerContainerEl.appendChild(logEl);
+ loggerContainerEl.scrollTop = loggerContainerEl.scrollHeight;
+
+ imgCache.set(imgName, new WeakRef(newImg));
+ registry.register(newImg, {
+ imgName,
+ size: newImg.size,
+ type: newImg.type,
+ });
+
+ return newImg;
+ };
+};
+
+export const stateObj = {
+ loading: false,
+ drawing: true,
+ collageRendered: false,
+ currentLayout: LAYOUTS[0],
+ selectedImages: new Set(),
+};
diff --git a/2-ui/1-document/01-browser-environment/article.md b/2-ui/1-document/01-browser-environment/article.md
index e61f89e66..40840d960 100644
--- a/2-ui/1-document/01-browser-environment/article.md
+++ b/2-ui/1-document/01-browser-environment/article.md
@@ -1,10 +1,18 @@
# Ø¨ÙØ¦Ø© اÙÙ
ØªØµÙØ ÙÙ
ÙØ§ØµÙاتÙ
+<<<<<<< HEAD
تÙ
Ø¥ÙØ´Ø§Ø¡ ÙØºØ© JavaScript ÙÙ Ø§ÙØ¨Ø¯Ø§ÙØ© ÙÙ
ØªØµÙØØ§Øª اÙÙÙØ¨Ø Ù
ÙØ° ذÙÙ Ø§ÙØÙÙ Ø£ØµØ¨Ø ÙÙØ§ استخدÙ
ات ÙÙ
ÙØµØ§Øª Ø¹Ø¯ÙØ¯Ø©.
ÙØ¯ تÙÙ٠تÙ٠اÙÙ
ÙØµØ© Ù
ØªØµÙØØ Ø®Ø§Ø¯ÙÙ
ÙÙØ¨ ا٠*Ù
ضÙÙ* آخر ÙÙÙÙ ÙÙÙ ÙØ§ØØ¯ Ù
ÙÙÙ
ÙØ¸ÙÙØªÙ Ø§ÙØ®Ø§ØµØ© Ø§ÙØªÙ ÙÙÙÙ
Ø¨ÙØ§ .خصائص اÙÙ JavaScript تسÙ
Ù ÙØ°Ø§ *Ø¨Ø¨ÙØ¦Ø© اÙÙ
ضÙÙ*.
تÙÙØ± Ø¨ÙØ¦Ø© Ø§ÙØ¹Ù
Ù ÙØ§Ø¦Ùات Ù ÙØ¸Ø§Ø¦Ù خاصة Ø¥ÙÙ ÙÙØ§Ø© اÙÙØºØ©. تعتبر اÙÙ
ØªØµÙØØ§Øª ÙØ³ÙÙØ© ÙÙØªØÙÙ
Ø¨ØµÙØØ§Øª اÙÙÙØ¨. ÙØªÙÙØ± اÙÙ Node.js Ø®ÙØ§Øµ Ù
Ù Ø¬Ø§ÙØ¨ Ø§ÙØ®Ø§Ø¯Ù
, ÙÙ
ا Ø¥Ù٠ذÙÙ.
+=======
+The JavaScript language was initially created for web browsers. Since then, it has evolved into a language with many uses and platforms.
+
+A platform may be a browser, or a web-server or another *host*, or even a "smart" coffee machine if it can run JavaScript. Each of these provides platform-specific functionality. The JavaScript specification calls that a *host environment*.
+
+A host environment provides its own objects and functions in addition to the language core. Web browsers give a means to control web pages. Node.js provides server-side features, and so on.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¥ÙÙÙ ÙØ¸Ø±Ø© شاÙ
ÙØ© ÙÙ
ا ÙØ¯ÙÙØ§ Ø¹ÙØ¯ تشغÙÙ Ø¬Ø§ÙØ§ Ø³ÙØ±Ùبت ÙÙ Ù
ØªØµÙØ ÙÙØ¨:
@@ -12,11 +20,18 @@
ÙØ¯ÙÙØ§ ÙØ§Ø¦Ù "Ø§ÙØ¬Ø°Ø±" `window` . ÙÙ Ø¯ÙØ±ÙÙ:
+<<<<<<< HEAD
1. Ø£ÙÙØ§Ø ÙÙ ÙØ§Ø¦Ù عاÙ
ÙØ´Ùرة JavaScriptØ ÙÙ
ا ÙØµÙÙ ÙÙ ÙØµÙ
2. ثاÙÙÙØ§Ø ÙÙ
ث٠"ÙØ§Ùذة اÙÙ
ØªØµÙØ" ÙÙÙÙØ± Ø·Ø±ÙØ§ ÙÙØªØÙÙ
ÙÙÙØ§.
عÙ٠سبÙ٠اÙÙ
Ø«Ø§ÙØ ÙØ³ØªØ®Ø¯Ù
ÙØ§ ÙÙØ§ ÙÙØ§Ø¦Ù عاÙ
:
+=======
+1. First, it is a global object for JavaScript code, as described in the chapter .
+2. Second, it represents the "browser window" and provides methods to control it.
-```js run
+For instance, we can use it as a global object:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
+
+```js run global
function sayHi() {
alert("Hello");
}
@@ -25,17 +40,29 @@ function sayHi() {
window.sayHi();
```
+<<<<<<< HEAD
ÙÙÙØ§ ÙØ³ØªØ®Ø¯Ù
ÙØ§ ÙÙØ§Ùذة Ù
ØªØµÙØ ÙØ±Ø¤ÙØ© Ø§Ø±ØªÙØ§Ø¹ اÙÙØ§Ùذة:
+=======
+And we can use it as a browser window, to show the window height:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```js run
alert(window.innerHeight); // Ø§Ø±ØªÙØ§Ø¹ اÙÙØ§Ùذة Ø§ÙØ¯Ø§Ø®ÙÙØ©
```
+<<<<<<< HEAD
ÙÙØ§Ù اÙÙ
Ø²ÙØ¯ Ù
Ù Ø§ÙØ£Ø³Ø§ÙÙØ¨ ÙØ§Ùخصائص Ø§ÙØ®Ø§ØµØ© باÙÙØ§ÙØ°Ø©Ø ÙØ³ÙغطÙÙØ§ ÙØ§ØÙÙØ§.
## DOM (Document Object Model)
ÙÙ
ث٠ÙÙ
ÙØ°Ø¬ ÙØ§Ø¦Ù اÙÙ
Ø³ØªÙØ¯Ø أ٠اختصار DOMØ Ù
ØØªÙÙ Ø§ÙØµÙØØ© باÙÙØ§Ù
Ù ÙÙØ§Ø¦Ùات ÙÙ
Ù٠تعدÙÙÙØ§.
+=======
+There are more window-specific methods and properties, which we'll cover later.
+
+## DOM (Document Object Model)
+
+The Document Object Model, or DOM for short, represents all page content as objects that can be modified.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ§Ø¦Ù `document` ÙÙ "ÙÙØ·Ø© Ø§ÙØ¯Ø®ÙÙ" Ø§ÙØ±Ø¦ÙØ³ÙØ© ÙÙØµÙØØ©. ÙÙ
ÙÙÙØ§ تغÙÙØ± Ø£Ù Ø¥ÙØ´Ø§Ø¡ Ø£Ù Ø´ÙØ¡ عÙÙ Ø§ÙØµÙØØ© باستخداÙ
Ù.
@@ -49,18 +76,30 @@ document.body.style.background = "red";
setTimeout(() => document.body.style.background = "", 1000);
```
+<<<<<<< HEAD
استخدÙ
ÙØ§ ÙÙØ§ `document.body.style`Ø ÙÙÙÙ ÙÙØ§Ù اÙÙØ«Ùر ÙØ§ÙÙØ«Ùر. ÙØªÙ
ÙØµÙ Ø§ÙØ®ØµØ§Ø¦Øµ ÙØ§ÙأساÙÙØ¨ Ù٠اÙÙ
ÙØ§ØµÙات: **DOM Ø§ÙØØ§ÙØ© اÙÙÙØ§Ø³ÙØ©** ÙÙ
+=======
+Here, we used `document.body.style`, but there's much, much more. Properties and methods are described in the specification: [DOM Living Standard](https://dom.spec.whatwg.org).
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```smart header="DOM ÙÙØ³ ÙÙØ· ÙÙÙ
ØªØµÙØØ§Øª"
ØªÙØ¶Ø Ù
ÙØ§ØµÙات اÙÙ DOM بÙÙØ© اÙÙ
Ø³ØªÙØ¯ ÙØªÙÙØ± ÙØ§Ø¦Ùات ÙÙ
Ø¹Ø§ÙØ¬ØªÙ. ÙÙØ§Ù Ø£Ø¯ÙØ§Øª ØºÙØ± اÙÙ
ØªØµÙØ تستخدÙ
اÙÙ DOM Ø£ÙØ¶Ùا.
+<<<<<<< HEAD
عÙ٠سبÙ٠اÙÙ
Ø«Ø§ÙØ ÙÙ
ÙÙ ÙÙØ¨Ø±Ø§Ù
ج اÙÙØµÙØ© Ù
Ù Ø¬Ø§ÙØ¨ Ø§ÙØ®Ø§Ø¯ÙÙ
Ø§ÙØªÙ تÙÙÙ
Ø¨ØªÙØ²ÙÙ ØµÙØØ§Øª HTML ÙÙ
Ø¹Ø§ÙØ¬ØªÙا Ø£ÙØ¶Ùا استخداÙ
اÙÙDOM. ÙØ¯ ÙØ¯Ø¹Ù
ÙÙ Ø¬Ø²Ø¡ÙØ§ ÙÙØ· Ù
٠اÙÙ
ÙØ§ØµÙات Ø¨Ø§ÙØ±ØºÙ
Ù
٠ذÙÙ.
+=======
+For instance, server-side scripts that download HTML pages and process them can also use the DOM. They may support only a part of the specification though.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
ÙØªÙ
استخداÙ
CSSOM Ù
ع اÙÙ DOM Ø¹ÙØ¯ تعدÙÙ ÙÙØ§Ø¹Ø¯ اÙÙÙ
Ø· ÙÙÙ
Ø³ØªÙØ¯. Ù
٠اÙÙØ§ØÙØ© Ø§ÙØ¹Ù
ÙÙØ©Ø ÙØ§Ø¯Ø±Ùا Ù
ا تÙÙÙ CSSOM Ù
Ø·ÙÙØ¨Ø©Ø ÙØ£Ù ÙÙØ§Ø¹Ø¯ CSS عادة Ù
ا تÙÙ٠ثابتة. ÙØ§Ø¯Ø±Ùا Ù
ا ÙØØªØ§Ø¬ Ø¥ÙÙ Ø¥Ø¶Ø§ÙØ©/Ø¥Ø²Ø§ÙØ© ÙÙØ§Ø¹Ø¯ اÙÙ CSS Ù
٠اÙÙ JavaScriptØ ÙÙÙÙ ÙØ°Ø§ Ù
Ù
ÙÙ Ø£ÙØ¶Ùا.
+<<<<<<< HEAD
```smart header="CSSOM ÙÙØªØµÙÙÙ"
ÙØªÙ
ØªÙØ¸ÙÙ
ÙÙØ§Ø¹Ø¯ CSS ÙØ£ÙØ±Ø§Ù Ø§ÙØ£ÙÙ
اط بطرÙÙØ© Ù
ختÙÙØ© ع٠HTML. ÙÙØ§Ù Ù
ÙØ§ØµÙات Ù
ÙÙØµÙØ©Ø [CSS Object Model (CSSOM)](https://www.w3.org/TR/cssom-1/), ÙØ´Ø±Ø ÙÙÙ ÙØªÙ
تÙ
Ø«ÙÙÙØ§ ÙÙØ§Ø¦ÙØ§ØªØ ÙÙÙÙÙØ© ÙØ±Ø§Ø¡ØªÙا ÙÙØªØ§Ø¨ØªÙا.
+=======
+The CSSOM is used together with the DOM when we modify style rules for the document. In practice though, the CSSOM is rarely required, because we rarely need to modify CSS rules from JavaScript (usually we just add/remove CSS classes, not modify their CSS rules), but that's also possible.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
## BOM (Browser Object Model)
@@ -69,8 +108,13 @@ setTimeout(() => document.body.style.background = "", 1000);
عÙ٠سبÙ٠اÙÙ
ثاÙ:
+<<<<<<< HEAD
- ÙÙÙØ± ÙØ§Ø¦Ù [navigator](mdn:api/Window/navigator) Ù
عÙÙÙ
ات Ø£Ø³Ø§Ø³ÙØ© ØÙ٠اÙÙ
ØªØµÙØ ÙÙØ¸Ø§Ù
Ø§ÙØªØ´ØºÙÙ. ÙÙØ§Ù Ø§ÙØ¹Ø¯Ùد Ù
Ù Ø§ÙØ®ØµØ§Ø¦Øµ Ø ÙÙÙ Ø§ÙØ£Ùثر Ø´ÙØ±Ø© ÙÙ
ا: `navigator.userAgent` -- ØÙ٠اÙÙ
ØªØµÙØ Ø§ÙØØ§ÙÙØ Ù `navigator.platform` -- ØÙ٠اÙÙØ¸Ø§Ù
Ø§ÙØ£Ø³Ø§Ø³Ù (ÙÙ
ÙÙ Ø£Ù ÙØ³Ø§Ø¹Ø¯ عÙÙ ØªØØ¯Ùد Ø§ÙØ§Ø®ØªÙا٠بÙÙ Windows/Linux/Mac Ø¥ÙØ®).
- ÙØ³Ù
Ø ÙÙØ§ ÙØ§Ø¦Ù [location](mdn:api/Window/location) Ø¨ÙØ±Ø§Ø¡Ø© عÙÙØ§Ù URL Ø§ÙØØ§ÙÙ ÙÙÙ
ÙÙ٠إعادة ØªÙØ¬Ù٠اÙÙ
ØªØµÙØ Ø¥Ù٠عÙÙØ§Ù Ø¬Ø¯ÙØ¯.
+=======
+- The [navigator](mdn:api/Window/navigator) object provides background information about the browser and the operating system. There are many properties, but the two most widely known are: `navigator.userAgent` -- about the current browser, and `navigator.platform` -- about the platform (can help to differentiate between Windows/Linux/Mac etc).
+- The [location](mdn:api/Window/location) object allows us to read the current URL and can redirect the browser to a new one.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ø¥ÙÙÙ ÙÙÙÙØ© استخداÙ
ÙØ§Ø¦Ù `location`:
@@ -81,33 +125,60 @@ if (confirm("Go to Wikipedia?")) {
}
```
+<<<<<<< HEAD
تعد Ø§ÙØ¯Ùا٠`alert/confirm/prompt` Ø¬Ø²Ø¡ÙØ§ Ù
٠اÙÙ BOM: ÙÙÙ ÙØ§ تتعÙÙ Ù
باشرة باÙÙ
Ø³ØªÙØ¯Ø ÙÙÙÙÙØ§ تÙ
ث٠طر٠Ù
ØªØµÙØ Ø®Ø§ÙØµØ© ÙÙØªÙاص٠Ù
ع اÙÙ
ستخدÙ
.
```smart header="Ù
ÙØ§ØµÙات"
BOM Ù٠جزء Ù
Ù Ù
ÙØ§ØµÙات[HTML specification](https://html.spec.whatwg.org).
ÙØ¹Ù
سÙ
عت ذÙÙ Ø¬ÙØ¯Ø§. Ù
ÙØ§ØµÙات اÙÙ HTML ÙÙ ÙØ§ تتعÙÙ ÙÙØ· ب٠"ÙØºØ© HTML" (Ø§ÙØ¹ÙاÙ
Ø§ØªØ Ø§ÙØ³Ù
ات) ØÙÙÙÙÙ ÙØºØ·Ù Ø£ÙØ¶Ùا Ù
جÙ
ÙØ¹Ø© Ù
٠اÙÙØ§Ø¦Ùات ÙØ§ÙأساÙÙØ¨ ÙØ¥Ø¶Ø§Ùات DOM Ø§ÙØ®Ø§ØµØ© باÙÙ
ØªØµÙØ. ÙØ°Ø§ ÙÙ "اÙÙ HTML بعبارات عاÙ
Ø©".Ø£ÙØ¶ÙØ§Ø ØªØØªÙ٠بعض Ø§ÙØ£Ø¬Ø²Ø§Ø¡ عÙÙ Ù
ÙØ§ØµÙات إضاÙÙØ© Ù
درجة ÙÙ .
+=======
+The functions `alert/confirm/prompt` are also a part of the BOM: they are not directly related to the document, but represent pure browser methods for communicating with the user.
+
+```smart header="Specifications"
+The BOM is a part of the general [HTML specification](https://html.spec.whatwg.org).
+
+Yes, you heard that right. The HTML spec at is not only about the "HTML language" (tags, attributes), but also covers a bunch of objects, methods, and browser-specific DOM extensions. That's "HTML in broad terms". Also, some parts have additional specs listed at .
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```
## Ù
ÙØ®Øµ
Ø¨Ø§ÙØØ¯ÙØ« ع٠اÙÙ
عاÙÙØ±Ø ÙØ¯ÙÙØ§:
+<<<<<<< HEAD
Ù
ÙØ§ØµÙات اÙÙ DOM
: ÙØµÙ ÙÙÙ٠اÙÙØ«ÙÙØ© ÙØ§ÙØªÙØ§Ø¹Ø¨ ÙØ§ÙØ£ØØ¯Ø§Ø«Ø راجع .
Ù
ÙØ§ØµÙات اÙÙ CSSOM
: ÙØµÙ Ø£ÙØ±Ø§Ù Ø§ÙØ£ÙÙ
اط ÙÙÙØ§Ø¹Ø¯ Ø§ÙØ£ÙÙ
اط ÙØ§ÙØªÙØ§Ø¹Ø¨ Ø¨ÙØ§ ÙØ±Ø¨Ø·Ùا باÙÙ
Ø³ØªÙØ¯Ø§ØªØ راجع .
+=======
+DOM specification
+: Describes the document structure, manipulations, and events, see .
+
+CSSOM specification
+: Describes stylesheets and style rules, manipulations with them, and their binding to documents, see .
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
Ù
ÙØ§ØµÙات اÙÙ HTML
: ØªØµÙ ÙØºØ© HTML (Ù
Ø«Ù Ø§ÙØ¹ÙاÙ
ات) ÙÙØ°ÙÙ BOM (طراز ÙØ§Ø¦Ù اÙÙ
ØªØµÙØ) - ÙØ¸Ø§Ø¦Ù اÙÙ
ØªØµÙØ اÙÙ
ختÙÙØ©: `setTimeout`, `alert`, `location` ÙÙ
ا Ø¥Ù٠ذÙÙØ راجع . ÙØ£Ø®Ø° Ù
ÙØ§ØµÙات اÙÙ DOM ÙÙÙØ³Ø¹Ùا Ø¨Ø§ÙØ¹Ø¯Ùد Ù
Ù Ø§ÙØ®ØµØ§Ø¦Øµ ÙØ§ÙأساÙÙØ¨ Ø§ÙØ¥Ø¶Ø§ÙÙØ©.
Ø¨Ø§ÙØ¥Ø¶Ø§ÙØ© Ø¥Ù٠ذÙÙØ ÙØªÙ
ÙØµÙ بعض اÙÙØ¦Ø§Øª بشÙÙ Ù
ÙÙØµÙ ÙÙ .
+<<<<<<< HEAD
ÙØ±Ø¬Ù Ù
ÙØ§ØØ¸Ø© ÙØ°Ù Ø§ÙØ±ÙØ§Ø¨Ø·Ø ØÙØ« Ø£Ù ÙÙØ§Ù اÙÙØ«Ùر Ù
Ù Ø§ÙØ£Ø´Ùاء ÙÙ
Ø¹Ø±ÙØ© Ø£ÙÙ Ù
٠اÙÙ
ستØÙÙ ØªØºØ·ÙØ© ÙØªØ°Ùر ÙÙ Ø´ÙØ¡.
Ø¹ÙØ¯Ù
ا ترغب Ù٠اÙÙØ±Ø§Ø¡Ø© Ø¹Ù Ø®Ø§ØµÙØ© أ٠طرÙÙØ© Ù
Ø§Ø ÙØ¥Ù دÙÙÙ Mozilla عÙÙ ÙÙ Ø£ÙØ¶Ùا Ù
ÙØ±Ø¯ Ø¬ÙØ¯Ø ÙÙÙ٠اÙÙ
ÙØ§ØµÙات اÙÙ
ÙØ§Ø¨ÙØ© ÙØ¯ تÙÙÙ Ø£ÙØ¶Ù: Ø¥ÙÙØ§ Ø£ÙØ«Ø± تعÙÙØ¯Ùا ÙØ£Ø·ÙÙ ÙÙØªÙا ÙÙÙØ±Ø§Ø¡Ø©Ø ÙÙÙÙÙØ§ ستجع٠Ù
Ø¹Ø±ÙØªÙ Ø§ÙØ£Ø³Ø§Ø³ÙØ© سÙÙÙ
Ø© ÙÙØ§Ù
ÙØ©.
+=======
+Please note these links, as there's so much to learn that it's impossible to cover everything and remember it all.
+
+When you'd like to read about a property or a method, the Mozilla manual at is also a nice resource, but the corresponding spec may be better: it's more complex and longer to read, but will make your fundamental knowledge sound and complete.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ¹Ø«Ùر عÙÙ Ø´ÙØ¡ Ù
Ø§Ø ØºØ§ÙØ¨Ùا Ù
ا ÙÙÙÙ Ù
٠اÙÙ
ÙØ§Ø¦Ù
استخداÙ
Ø§ÙØ¨ØØ« عÙÙ Ø§ÙØ¥ÙØªØ±ÙØª "WHATWG [Ù
ØµØ·ÙØ]" ا٠"MDN [Ù
ØµØ·ÙØ]", Ù
ث٠, .
+<<<<<<< HEAD
Ø³ÙØ¨Ø¯Ø£ Ø§ÙØ¢Ù Ù٠تعÙÙ
اÙÙ DOM, ÙØ£Ù اÙÙ
Ø³ØªÙØ¯ ÙÙØ¹Ø¨ Ø§ÙØ¯Ùر اÙÙ
Ø±ÙØ²Ù ÙÙ ÙØ§Ø¬ÙØ© اÙÙ
ستخدÙ
.
+=======
+Now, we'll get down to learning the DOM, because the document plays the central role in the UI.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
diff --git a/2-ui/1-document/02-dom-nodes/article.md b/2-ui/1-document/02-dom-nodes/article.md
index 126816e5c..9be222bee 100644
--- a/2-ui/1-document/02-dom-nodes/article.md
+++ b/2-ui/1-document/02-dom-nodes/article.md
@@ -52,7 +52,7 @@ setTimeout(() => (document.body.style.background = ''), 3000); // ÙØ¥Ø²Ø§ÙØ©
@@ -227,7 +227,11 @@ Even the `` directive at the very beginning of HTML is also a DOM n
## Ø§ÙØ¸Ø± بÙÙØ³Ù
+<<<<<<< HEAD
ÙÙ
Ø´Ø§ÙØ¯Ø© بÙÙØ© ÙÙ
ÙØ°Ø¬ ÙØ§Ø¦Ù اÙÙ
Ø³ØªÙØ¯ Ù
Ø¨Ø§Ø´Ø±Ø©Ø Ø¬Ø±Ø¨ استخداÙ
[Live DOM Viewer](http://software.hixie.ch/utilities/js/live-dom-viewer/). Ù
ا عÙÙ٠سÙ٠اÙÙØªØ§Ø¨Ø© Ù٠اÙÙ
Ø³ØªÙØ¯Ø ÙØ³ÙØ¸ÙØ± ÙÙÙ
ÙØ°Ø¬ ÙØ§Ø¦Ù Ù
Ø³ØªÙØ¯ ÙÙ Ø§ÙØØ§Ù.
+=======
+To see the DOM structure in real-time, try [Live DOM Viewer](https://software.hixie.ch/utilities/js/live-dom-viewer/). Just type in the document, and it will show up as a DOM at an instant.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙØ§Ù طرÙÙØ© Ø£Ø®Ø±Ù ÙØ§Ø³ØªÙشا٠ÙÙ
ÙØ°Ø¬ ÙØ§Ø¦Ù اÙÙ
Ø³ØªÙØ¯ ÙÙ٠استخداÙ
Ø£Ø¯ÙØ§Øª Ù
Ø·ÙØ± اÙÙ
ØªØµÙØ. ÙÙØ°Ø§ Ù
ا ÙØ³ØªØ®Ø¯Ù
Ù Ù٠اÙÙØ§Ùع Ø£Ø«ÙØ§Ø¡ Ø§ÙØªØ·ÙÙØ±.
diff --git a/2-ui/1-document/03-dom-navigation/article.md b/2-ui/1-document/03-dom-navigation/article.md
index 75c891953..f6261bc4c 100644
--- a/2-ui/1-document/03-dom-navigation/article.md
+++ b/2-ui/1-document/03-dom-navigation/article.md
@@ -214,7 +214,11 @@ alert(document.body.previousSibling); // HTMLHeadElement
## Ø§ÙØªÙÙÙ Ø§ÙØ®Ø§Øµ Ø¨Ø§ÙØ¹Ùاصر ÙÙØ·
+<<<<<<< HEAD
ØªØ´ÙØ± خصائص Ø§ÙØªÙÙ٠اÙÙ
ذÙÙØ±Ø© Ø£Ø¹ÙØ§Ù Ø¥ÙÙ _جÙ
ÙØ¹_ Ø§ÙØ¹Ùد. عÙ٠سبÙ٠اÙÙ
Ø«Ø§ÙØ ÙÙ `childNodes` ÙÙ
ÙÙÙØ§ Ø±Ø¤ÙØ© ÙÙ Ù
Ù Ø¹ÙØ¯ اÙÙØµÙص ÙØ¹Ùد Ø§ÙØ¹Ùاصر ÙØØªÙ Ø¹ÙØ¯ Ø§ÙØªØ¹ÙÙÙØ§Øª إذا ÙØ§Ùت Ù
ÙØ¬Ùدة.
+=======
+Navigation properties listed above refer to *all* nodes. For instance, in `childNodes` we can see both text nodes, element nodes, and even comment nodes if they exist.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙÙÙÙ ÙÙØ¹Ø¯Ùد Ù
٠اÙÙ
ÙØ§Ù
ÙØ§ ÙØ±Ùد Ø¹ÙØ¯ اÙÙØµÙص Ø£Ù Ø§ÙØªØ¹ÙÙÙØ§Øª. ÙØ±Ùد Ø§ÙØªÙاعب Ø¨Ø¹ÙØ¯ Ø§ÙØ¹Ùاصر Ø§ÙØªÙ تÙ
Ø«Ù Ø§ÙØ¹ÙاÙ
ات ÙØªØ´ÙÙ ÙÙÙÙ Ø§ÙØµÙØØ©.
diff --git a/2-ui/1-document/04-searching-elements-dom/article.md b/2-ui/1-document/04-searching-elements-dom/article.md
index 5af6435ce..405129694 100644
--- a/2-ui/1-document/04-searching-elements-dom/article.md
+++ b/2-ui/1-document/04-searching-elements-dom/article.md
@@ -55,7 +55,7 @@ Also, there's a global variable named by `id` that references the element:
```
```warn header="Please don't use id-named global variables to access elements"
-This behavior is described [in the specification](http://www.whatwg.org/specs/web-apps/current-work/#dom-window-nameditem), so it's kind of standard. But it is supported mainly for compatibility.
+This behavior is described [in the specification](https://html.spec.whatwg.org/multipage/window-object.html#named-access-on-the-window-object), but it is supported mainly for compatibility.
The browser tries to help us by mixing namespaces of JS and DOM. That's fine for simple scripts, inlined into HTML, but generally isn't a good thing. There may be naming conflicts. Also, when one reads JS code and doesn't have HTML in view, it's not obvious where the variable comes from.
@@ -116,7 +116,7 @@ In other words, the result is the same as `elem.querySelectorAll(css)[0]`, but t
Previous methods were searching the DOM.
-The [elem.matches(css)](http://dom.spec.whatwg.org/#dom-element-matches) does not look for anything, it merely checks if `elem` matches the given CSS-selector. It returns `true` or `false`.
+The [elem.matches(css)](https://dom.spec.whatwg.org/#dom-element-matches) does not look for anything, it merely checks if `elem` matches the given CSS-selector. It returns `true` or `false`.
The method comes in handy when we are iterating over elements (like in an array or something) and trying to filter out those that interest us.
@@ -154,7 +154,7 @@ For instance:
- Chapter 1
- - Chapter 1
+ - Chapter 2
diff --git a/2-ui/1-document/05-basic-dom-node-properties/article.md b/2-ui/1-document/05-basic-dom-node-properties/article.md
index d9a2afa0c..8b713d6cf 100644
--- a/2-ui/1-document/05-basic-dom-node-properties/article.md
+++ b/2-ui/1-document/05-basic-dom-node-properties/article.md
@@ -10,7 +10,11 @@
ØªÙØªÙ
Ù ÙÙ Ø¹ÙØ¯Ø© DOM Ø¥Ù٠اÙÙØ¦Ø© اÙÙ
ضÙ
ÙØ© اÙÙ
ÙØ§Ø¨ÙØ©.
+<<<<<<< HEAD
جذر Ø§ÙØªØ³Ùس٠اÙÙØ±Ù
Ù ÙÙ [EventTarget] (https://dom.spec.whatwg.org/#eventtarget) Ø Ø§ÙÙ
ÙØ±ÙØ« Ø¨ÙØ§Ø³Ø·Ø© [Node] (http://dom.spec.whatwg.org/#interface-node ) Ø ÙØªØ±Ø« Ø§ÙØ¹Ùد Ø§ÙØ£Ø®Ø±Ù Ù
ÙÙ.
+=======
+The root of the hierarchy is [EventTarget](https://dom.spec.whatwg.org/#eventtarget), that is inherited by [Node](https://dom.spec.whatwg.org/#interface-node), and other DOM nodes inherit from it.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
ÙØ°Ù ÙÙ Ø§ÙØµÙرة ÙØ§ÙØªÙØ³Ùرات Ø§ÙØªÙ ÙØ¬Ø¨ Ø§ØªØ¨Ø§Ø¹ÙØ§:
@@ -18,6 +22,7 @@
اÙclasses ÙÙ:
+<<<<<<< HEAD
- [EventTarget] (https://dom.spec.whatwg.org/#eventtarget) - ÙÙ ÙØ¦Ø© Ø§ÙØ¬Ø°Ø± "اÙÙ
جردة". ÙØ§ ÙØªÙ
Ø¥ÙØ´Ø§Ø¡ ÙØ§Ø¦Ùات ÙØ°Ù اÙÙØ¦Ø© Ø£Ø¨Ø¯ÙØ§. Ø¥Ù٠بÙ
ثابة ÙØ§Ø¹Ø¯Ø© Ø Ø¨ØÙØ« تدعÙ
جÙ
ÙØ¹ Ø¹ÙØ¯ DOM Ù
ا ÙØ³Ù
Ù "Ø§ÙØ£ØØ¯Ø§Ø«" Ø ÙØ³ÙØ¯Ø±Ø³ÙØ§ ÙØ§ØÙÙØ§.
- [Node] (http://dom.spec.whatwg.org/#interface-node) - ÙÙ Ø£ÙØ¶Ùا ÙØ¦Ø© "Ù
جردة" Ø ØªØ¹Ù
Ù ÙÙØ§Ø¹Ø¯Ø© ÙØ¹Ùد DOM. ÙÙÙØ± ÙØ¸Ø§Ø¦Ù Ø§ÙØ´Ø¬Ø±Ø© Ø§ÙØ£Ø³Ø§Ø³ÙØ©: `motherNode` Ù` nextSibling` Ù` childNodes` ÙÙ
ا Ø¥Ù٠ذÙÙ (ÙÙ٠عبارة Ø¹Ù ØØ±ÙÙ). ÙØ§ ÙØªÙ
Ø¥ÙØ´Ø§Ø¡ ÙØ§Ø¦Ùات ÙØ¦Ø© "Ø§ÙØ¹Ùدة" Ù
Ø·ÙÙÙØ§. ÙÙÙÙ ÙÙØ§Ù ÙØ¦Ø§Øª Ø¹ÙØ¯Ø© Ù
ØØ¯Ø¯Ø© ترث Ù
ÙÙ Ø ÙÙÙ: `Text` ÙÙØ¹Ùد اÙÙØµÙØ© Ù` Element` ÙØ¹Ùد Ø§ÙØ¹Ùاصر ÙØ§ÙÙ
Ø²ÙØ¯ Ù
Ù Ø§ÙØ£ÙÙØ§Ø¹ Ø§ÙØºØ±Ùبة Ù
ث٠`Comment` ÙØ¹Ùد Ø§ÙØªØ¹ÙÙÙ.
- [Element] (http://dom.spec.whatwg.org/#interface-element) - ÙÙ ÙØ¦Ø© Ø£Ø³Ø§Ø³ÙØ© ÙØ¹Ùاصر DOM. ÙÙÙØ± Ø§ÙØªÙÙ٠عÙÙ Ù
ستÙÙ Ø§ÙØ¹Ùصر Ù
ث٠`nextElementSibling` Ù` children` ÙØ·Ø±Ù Ø§ÙØ¨ØØ« Ù
ث٠`getElementsByTagName` Ù` querySelector`. ÙØ§ ÙØ¯Ø¹Ù
اÙÙ
ØªØµÙØ HTML ÙØØ³Ø¨ Ø Ø¨Ù ÙØ¯Ø¹Ù
Ø£ÙØ¶Ùا XML Ù SVG. تعÙ
Ù ÙØ¦Ø© `Element` ÙÙØ§Ø¹Ø¯Ø© ÙÙØ¦Ø§Øª Ø£ÙØ«Ø± ØªØØ¯ÙØ¯ÙØ§:` SVGElement` Ù `XMLElement` Ù` HTMLElement`.
@@ -28,6 +33,41 @@
    - ... ÙÙÙØ°Ø§ Ø ÙÙ Ø¹ÙØ§Ù
Ø© ÙÙØ§ ÙØ¦Ø© خاصة Ø¨ÙØ§ ÙØ¯ تÙÙØ± خصائص ÙØ£Ø³Ø§ÙÙØ¨ Ù
عÙÙØ©.
ÙØ°ÙÙ Ø ÙØ¥Ù اÙÙ
جÙ
ÙØ¹Ø© اÙÙØ§Ù
ÙØ© Ù
Ù Ø§ÙØ®ØµØ§Ø¦Øµ ÙØ§ÙأساÙÙØ¨ ÙØ¹Ùدة Ù
عÙÙØ© ØªØ£ØªÙ ÙØªÙجة اÙÙ
ÙØ±Ø§Ø«.
+=======
+- [EventTarget](https://dom.spec.whatwg.org/#eventtarget) -- is the root "abstract" class for everything.
+
+ Objects of that class are never created. It serves as a base, so that all DOM nodes support so-called "events", we'll study them later.
+
+- [Node](https://dom.spec.whatwg.org/#interface-node) -- is also an "abstract" class, serving as a base for DOM nodes.
+
+ It provides the core tree functionality: `parentNode`, `nextSibling`, `childNodes` and so on (they are getters). Objects of `Node` class are never created. But there are other classes that inherit from it (and so inherit the `Node` functionality).
+
+- [Document](https://dom.spec.whatwg.org/#interface-document), for historical reasons often inherited by `HTMLDocument` (though the latest spec doesn't dictate it) -- is a document as a whole.
+
+ The `document` global object belongs exactly to this class. It serves as an entry point to the DOM.
+
+- [CharacterData](https://dom.spec.whatwg.org/#interface-characterdata) -- an "abstract" class, inherited by:
+ - [Text](https://dom.spec.whatwg.org/#interface-text) -- the class corresponding to a text inside elements, e.g. `Hello` in `Hello
`.
+ - [Comment](https://dom.spec.whatwg.org/#interface-comment) -- the class for comments. They are not shown, but each comment becomes a member of DOM.
+
+- [Element](https://dom.spec.whatwg.org/#interface-element) -- is the base class for DOM elements.
+
+ It provides element-level navigation like `nextElementSibling`, `children` and searching methods like `getElementsByTagName`, `querySelector`.
+
+ A browser supports not only HTML, but also XML and SVG. So the `Element` class serves as a base for more specific classes: `SVGElement`, `XMLElement` (we don't need them here) and `HTMLElement`.
+
+- Finally, [HTMLElement](https://html.spec.whatwg.org/multipage/dom.html#htmlelement) is the basic class for all HTML elements. We'll work with it most of the time.
+
+ It is inherited by concrete HTML elements:
+ - [HTMLInputElement](https://html.spec.whatwg.org/multipage/forms.html#htmlinputelement) -- the class for `` elements,
+ - [HTMLBodyElement](https://html.spec.whatwg.org/multipage/semantics.html#htmlbodyelement) -- the class for `` elements,
+ - [HTMLAnchorElement](https://html.spec.whatwg.org/multipage/semantics.html#htmlanchorelement) -- the class for `` elements,
+ - ...and so on.
+
+There are many other tags with their own classes that may have specific properties and methods, while some elements, such as ``, ``, `` do not have any specific properties, so they are instances of `HTMLElement` class.
+
+So, the full set of properties and methods of a given node comes as the result of the chain of inheritance.
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
عÙ٠سبÙ٠اÙÙ
Ø«Ø§Ù Ø ÙÙÙÙØ± ÙÙ ÙØ§Ø¦Ù DOM ÙØ¹Ùصر ``. ÙÙÙ ØªÙØªÙ
٠إÙÙ ÙØ¦Ø© [HTMLInputElement] (https://html.spec.whatwg.org/multipage/forms.html#htmlinputelement).
@@ -133,10 +173,10 @@ alert(document.body instanceof EventTarget); // true
```
+<<<<<<< HEAD
ÙÙÙÙ ÙÙØ§Ù Ø§Ø³ØªØ«ÙØ§Ø¡Ø§Øª Ø Ø¹Ù٠سبÙ٠اÙÙ
Ø«Ø§Ù Ø ØªØªÙ
Ù
زاÙ
ÙØ© `input.value` ÙÙØ· Ù
Ù Ø§ÙØ³Ù
Ø© -> Ø¥ÙÙ Ø§ÙØ®Ø§ØµÙØ© Ø ÙÙÙÙ ÙÙØ³ Ù
رة أخرÙ:
+=======
+But there are exclusions, for instance `input.value` synchronizes only from attribute -> property, but not back:
+>>>>>>> ff804bc19351b72bc5df7766f4b9eb8249a3cb11
```html run
diff --git a/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html b/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html
index de8ec9aee..84ee26f19 100644
--- a/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html
+++ b/2-ui/1-document/07-modifying-document/10-clock-setinterval/solution.view/index.html
@@ -45,7 +45,7 @@
function clockStart() {
// set a new interval only if the clock is stopped
// otherwise we would rewrite the timerID reference to the running interval and wouldn't be able to stop the clock ever again
- if (!timerId) {
+ if (!timerId) {
timerId = setInterval(update, 1000);
}
update(); // <-- start right now, don't wait 1 second till the first setInterval works
@@ -56,7 +56,6 @@
timerId = null; // <-- clear timerID to indicate that the clock has been stopped, so that it is possible to start it again in clockStart()
}
- clockStart();
diff --git a/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md b/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md
index 6b85168b9..3d1f6698f 100644
--- a/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md
+++ b/2-ui/1-document/07-modifying-document/5-why-aaa/solution.md
@@ -1,9 +1,9 @@
The HTML in the task is incorrect. That's the reason of the odd thing.
-The browser has to fix it automatically. But there may be no text inside the ``: according to the spec only table-specific tags are allowed. So the browser adds `"aaa"` *before* the ``.
+The browser has to fix it automatically. But there may be no text inside the ``: according to the spec only table-specific tags are allowed. So the browser shows `"aaa"` *before* the ``.
Now it's obvious that when we remove the table, it remains.
-The question can be easily answered by exploring the DOM using the browser tools. It shows `"aaa"` before the `