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..23f3d94ae 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
- إضافة 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
من أمثلة هذه القيود:
- جافا سكريبت على صفحة الويب قد لا تقرأ/تكتب ملفات عشوائية على القرص الصلب أو تنسخها أو تنفذ برامج. ليس لديها وصول مباشر إلى وظائف نظام التشغيل.
+<<<<<<< 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
هناك طرق للتفاعل مع الكاميرا / الميكروفون والأجهزة الأخرى ، لكنها تتطلب إذنًا صريحًا من المستخدم. لذلك قد لا تعمل الصفحة التي تم تمكين جافا سكريبت فيها بشكل خفي على تمكين كاميرا الويب ومراقبة المناطق المحيطة وإرسال المعلومات إلى [آن آس أيه](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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## ما الذي يجعل جافا سكريبت فريدًا؟
هناك على الأقل *ثلاثة* أشياء رائعة حول جافا سكريبت:
```compare
+<<<<<<< HEAD
+ تكامل تام مع HTML / CSS.
+ الأشياء البسيطة تتم ببساطة.
+ مدعوم من قبل جميع المتصفحات الرائدة وتمكينه تلقائيا.
+=======
++ Full integration with HTML/CSS.
++ Simple things are done simply.
++ Supported by all major browsers and enabled by default.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
جافا سكريبت هي تقنية المتصفح الوحيدة التي تجمع بين هذه الأشياء الثلاثة.
+<<<<<<< HEAD
هذا ما يجعل جافا سكريبت فريدًا. هذا هو السبب في أنها الأداة الأكثر انتشارًا لإنشاء واجهات المتصفح.
+=======
+That said, JavaScript can be used to create servers, mobile applications, etc.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
ومع ذلك، تسمح جافا سكريبت أيضًا بإنشاء خوادم وتطبيقات الجوال، إلخ.
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
ظهرت في الآونة الأخيرة عدد كبير من اللغات الجديدة ، والتي *تم تحويلها* إلى جافا سكريبت قبل تشغيلها في المتصفح.
الأدوات الحديثة تجعل الترجمة سريعة وشفافة للغاية ، مما يسمح للمطورين في الواقع بالتشفير بلغة أخرى وتحويلها تلقائيًا "خلف الكواليس".
+<<<<<<< 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
هناك أكثر. بالطبع ، حتى لو استخدمنا إحدى اللغات المترجمة ، يجب أن نعرف أيضًا جافا سكريبت لفهم ما نقوم به حقًا.
+<<<<<<< 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..8382bc84a 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
[وصف 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 .
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
أيضاً، إذا كنت تطور من أجل المتصفح، إذا هناك مواصفات أخرى مشمولة في [الجزء الثاني](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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## جدول التوافق
جافا سكريبت لغة فى سياق متطور، تضاف إليها خصائص جديدة بانتظام.
+<<<<<<< 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
كل هذه المصادر مفيدة في تطوير الحياة الواقعية، لأنها تحتوي علي معلومات قيّمة عن تفاصيل ودعم اللغة.
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..10c027d98 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).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
بالنسبة للويندوز، يمكن استخدام برنامج فيجوال ستديو، لايجب الخلط بينه وبين الفيجوال ستديو كود، فيجوال ستديو هو محرر مدفوع يعمل على نظام ويندوز فقط، ومناسب تماماً لبيئة الـ.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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
المحررات أعلاه هي التي نقوم باستخدامها أنا وأصدقائي، والذين أعتقد أنهم مطورون جيدون يستخدمونها منذ وقت طويل وتسعدهم.
يوجد أيضاً محررات رائعة في عالمنا الكبير، الرجاء اختيار المحرر الذي تفضله.
+<<<<<<< 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).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
diff --git a/1-js/01-getting-started/4-devtools/article.md b/1-js/01-getting-started/4-devtools/article.md
index 3dded1566..65f237d33 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
أدوات المطور قوية, لديها العديد من الميزات. للبدء, سنتعلم كيفية فتحها ، والنظر في الأخطاء ، وتشغيل أوامر جافا سكريبت.
@@ -25,8 +29,12 @@
الآن أصبح بإمكانك استكشاف الأخطاء، وهذا يكفي بداية وسنعود لاحقًا إلى أدوات المطوَر لندرس استكشاف الأخطاء وإصلاحها أو ما يعرف debugging في فصل تنقيح الأخطاء في المتصفِّح Chrome.
+<<<<<<< HEAD
## أدوات المطور في متصفحي FireFox و Safari وغيرهما
تَستخدِم معظم المتصفِّحات الاختصار F12 لفتح أدوات المطوَر. بشكل عام تتشابه هذه الأدوات في الشكل والمضمون. وبمجرد تعلمك العمل على إحدى هذه الأدوات (بإمكانك البدء مع Chrome)، يمكنك بسهولة الانتقال للعمل على الأدوات الأخرى.
+=======
+
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
### أدوات المطور في متصفح 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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/chrome@2.webp b/1-js/01-getting-started/4-devtools/chrome@2.webp
new file mode 100644
index 000000000..2aeca5898
Binary files /dev/null and b/1-js/01-getting-started/4-devtools/chrome@2.webp differ
diff --git a/1-js/01-getting-started/4-devtools/chrome@2x.png b/1-js/01-getting-started/4-devtools/chrome@2x.png
deleted file mode 100644
index b87404a8f..000000000
Binary files a/1-js/01-getting-started/4-devtools/chrome@2x.png 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/safari@2x.png b/1-js/01-getting-started/4-devtools/safari@2x.png
index 27def4d09..1561b2bd9 100644
Binary files a/1-js/01-getting-started/4-devtools/safari@2x.png and b/1-js/01-getting-started/4-devtools/safari@2x.png 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..9338fa845 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
يمكن أن نعطي المسار الكامل أيضاً. على سبيل المثال :
diff --git a/1-js/02-first-steps/02-structure/article.md b/1-js/02-first-steps/02-structure/article.md
index 6285c198d..316f2cddd 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);
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
عند تنفيذ الشيفرة البرمجية آنذاك، سيتم إظهار التنبيه الأول فقط ثم سنحصل على خطأ. تعود الشيفرة البرمجية للعمل بشكل
صحيح مرة أخرى عند إضافة الفاصلة المنقوطة بعد التنبيه الأول:
+<<<<<<< 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);
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
ولكنهما عبارتين برمجيتين منفصلتين وليستا عبارة واحدة، وبالتالي عملية الدمج في هذه الحالة خطأ. من الممكن أن تتكرر
هذه الحالة ضمن شروط أخرى.
@@ -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.
+````
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
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..dd4bfe023 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
هل من الصحيح أستخدام الحروف الكبيره للثابت `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?
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
+```
diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md
index 89d21f287..f583e913f 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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
*/!*
```
@@ -66,7 +70,12 @@ let age = 25;
let message = 'Hello';
```
+<<<<<<< HEAD
بعض الناس ايضا يُعرفون المتغيرات بهذه الطريقه:
+=======
+Some people also define multiple variables in this multiline style:
+
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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 .
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
````
## التجانس الحقيقي
+<<<<<<< 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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b

نستطيع أن نضع أي قيمة بداخل الصندوق.
+<<<<<<< HEAD
ونستطيع أيضا تغيير قيمته أكثر من مره كما نريد.
+=======
+We can also change it as many times as we want:
+
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
في هذه اللغات, القيمه الاولي تُخزن في الصندوق, وتكون للابد. و اذا أردنا تخزين قيمه غيرها, اللغه تُنشئ لنا صندوق جديد (تعريف متغير جديد). ولا نستطيع أعاده استخدام المتغير القديم.
+<<<<<<< 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
## تسمية المتغير [#variable-naming]
@@ -192,20 +226,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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
````
````warn header="الأسماء المحجوزه"
@@ -260,12 +307,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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
### ثوابت ذات الحروف الكبيره
+<<<<<<< HEAD
هناك ممارسة شائعة لاستخدام الثوابت كأسماء مستعارة للقيم التي يصعب تذكرها والمعروفة قبل التنفيذ.
+=======
+There is a widespread practice to use constants as aliases for difficult-to-remember values that are known before execution.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
تتم تسمية هذه الثوابت باستخدام الأحرف الكبيرة والشرطات السفلية.
@@ -290,16 +345,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:
+
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## تسمية الاشياء بشكل صحيح
@@ -307,18 +375,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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
من فضلك خذ وقتك في اختيار اسم صحيح للمتغير قبل تعريفه. القيام بذلك سوف يسدد لك بسخاء
بعض القواعد الجيدة لأتباعها وهي :
+<<<<<<< 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
تبدو بسيطة؟ في الواقع ، ولكن إنشاء أسماء متغيرة وصفية وموجزة ليس كذلك. أذهب خلفها.
diff --git a/1-js/02-first-steps/05-types/article.md b/1-js/02-first-steps/05-types/article.md
index d555a8c24..8110aefa2 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`:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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`).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
`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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
النص في جافا سكريبت يتم إحاطته بعلامات تنصيص.
@@ -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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
يوجد 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
معامل `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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
في الفصول القادمة سنركز على القيم البدائية وعندما نكون متألفين معاهم، سنتجه للكائنات.
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..6b4a4b383 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
فيما بعد، بعد أن نتعلم عن الكائنات، في هذا الفصل سنرى كيف تتلائم الكائنات فيه.
```
@@ -34,7 +39,11 @@ alert(typeof value); // string
## التحويل الرقمي
+<<<<<<< HEAD
التحويل إلى رقم يتم أوتوماتيكياً في المعاملات والتعبيرات الرياضية.
+=======
+Numeric conversion in mathematical functions and expressions happens automatically.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
على سبيل المثال، في حالة القسمة `/` عندما يتم تطبيقها على نوع غير رقمي:
@@ -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`. |
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
أمثلة:
@@ -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`. |
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
**`التحويلات المنطقية`** -- يحدث في المعاملات المنطقية. يتم تنفيذه عن طريق `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..92dfe7469 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
diff --git a/1-js/02-first-steps/08-operators/article.md b/1-js/02-first-steps/08-operators/article.md
index f3b7469c2..130418973 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
على سبيل المثال:
```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 ½:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
عادة، عامل الإضافة "+" يقوم بجمع الأرقام
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## التعيين
+<<<<<<< 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
لهذا السبب ، عندما نقوم بتعيين متغير ، مثل `x = 2 * 2 + 1` ، تتم الحسابات أولاً ثم يتم تقييم` = `، وتخزين النتيجة في` x`.
@@ -309,9 +345,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 +478,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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## الفاصلة
diff --git a/1-js/02-first-steps/09-comparison/article.md b/1-js/02-first-steps/09-comparison/article.md
index 3dba72cc5..37f66d978 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
.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
في هذه المقالة سنتعلم المزيد عن الأنواع المختلفة من المقارنات ، وكيف تجعلها JavaScript، بما في ذلك الخصائص المهمة.
diff --git a/1-js/02-first-steps/10-ifelse/article.md b/1-js/02-first-steps/10-ifelse/article.md
index b733a4e7a..54f7ce005 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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!'`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
هنا ما يبدو عليه باستخدام `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..eb995eccc 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
في هذا المثال سيتم طباعة الرسالة الأولى ولن يتم طباعة الثانية:
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..2352bf7c5 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
نتيجة `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`:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js run
let user;
+<<<<<<< HEAD
alert(user ?? "مجهول الهوية"); // مجهول الهوية (لم يتم تحديد المستخدم)
+=======
+alert(user ?? "Anonymous"); // Anonymous (user is undefined)
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
هذا مثال على `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)
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
يمكننا أيضًا استخدام تسلسل `??` لتحديد القيمة الأولى من قائمة ليست `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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
لنستخدم عامل التحقق من الفراغ `??` لذلك:
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
من ناحية أخرى ، تمت إضافة عامل التحقق من الفراغ `??` إلى 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).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
وهذا يعني أنه مثل `||` ، يتم تقييم عامل التحقق من الفراغ `??` قبل `=` و `؟` ، ولكن بعد معظم العمليات الأخرى مثل `+` و `*`.
+<<<<<<< HEAD
لذلك إذا كنا نرغب في اختيار قيمة مع `??` في تعبير مع عوامل أخرى ، فكر في إضافة أقواس:
+=======
+So we may need to add parentheses in expressions like this:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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):
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..df001f080 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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
إن حلقة `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. |
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
الخوارزمية العامة للتكرار تعمل كالتالي:
@@ -173,12 +199,15 @@ for (i = 0; i < 3; i++) { // استخدام متغير معرف مسبقًا
alert(i); // 3, يمكن التعامل معه لأنه معرف خارج الحلقة
```
-
````
+<<<<<<< HEAD
### أجزاء يمكن تخطيها
أي جزء من `for` يمكن الاستغناء عنه.
+=======
+### Skipping parts
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
مثلًا إذا حذفنا `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.
+````
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
`````
@@ -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:
+
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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:
+
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
````
## ملخص
diff --git a/1-js/02-first-steps/14-switch/article.md b/1-js/02-first-steps/14-switch/article.md
index 1d63ee61d..7db5078df 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## الأنواع مهمة
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..b0d9a4fbd 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..ef7ad2c09 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..a0cb651a2 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
في هذا المثال الدالة لديها معاملين: `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` ولكن التغيير لا يؤثر في المتغير الممرر لأن الدالة تحصل على نسخة من القيمة:
+=======
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
على سبيل المثال الفنكشن السابقة `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 `=`:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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
+```
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
هنا استخدمنا النص `"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`:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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'
+=======
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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");
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
}
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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
## الدوال == تعليقات
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
تسمية الدوال:
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..2b0ff8c38 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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
يمكننا حتى طباعة هذه القيمة باستخدام `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" );
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
};
-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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
````
## 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
**المعاملات `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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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" `=`:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
...ولكن إذا كان 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..1aa41ae81 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();
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
}
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..040fa994b 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
بصيغة أخرى فهي إختصار ل:
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
- إذا كان لديك معامل واحد فقط فيمكن حذف الأقواس الدائرية من حوله لجعل التعبير أقصر.
@@ -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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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!");
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..207f7ebbe 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
جديرٌ بالذكر، أن بعضاً من هذه الميزات (كالصفوف التي سندرسها في المستقبل) تقوم بتفعيل هذا الوضع الحديث (الدقيق) بشكل ضمني حتى لو لم يتم كتابة التعليمة بشكل صريح.
@@ -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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
جميع التوابع السابقة هي عبارة عن ملاحظات شكلية أي يتم فتح نافذة صغيرة في أعلى الصفحة نفسها وتقوم بعرض السؤال، فتقوم هذه الملاحظة بإيقاف تنفيذ الكود البرمجي وتمنع المستخدم من التفاعل مع الصفحة حتى تتم الإجابة على السؤال المطروح.
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
العوامل الشرطية
: والعامل الشرطي هو العامل الوحيد الذي يأخذ ثلاث معاملات: `cond ? resultA : resultB`. فإذا كان الشرط `cond` صحيحاً، سيتمّ إرجاع `resultA` وإلا سيتم إرجاع `resultB`.
@@ -256,7 +276,11 @@ switch (age) {
3. الدوال كأسهم: (حيث تُرسم الدوال بطريقة تشبه شكل السهم)
```js
+<<<<<<< HEAD
// توضع التعابير في الطرف اليميني
+=======
+ // expression on the right side
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..f882ec8cf 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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
قبل كتابة أي كود معقد , فلنتحدث قليلا عن تصحيح الأخطاء.
@@ -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`:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b

@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
يكون هذا مفيدا عند الحاجة للتوقف فقط تبعا لمتغير معين أو معاملات دالة معينة.
```
+<<<<<<< HEAD
## أمر مصحح الخطأ(Debugger)
+=======
+## The command "debugger"
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
يمكننا أيضًا إيقاف الكود مؤقتًا باستخدام الأمر `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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
عند تعيين نقطة التوقف ، يتوقف التنفيذ مؤقتًا عند السطر الرابع:
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
يتم إيقاف التنفيذ بعد ذلك مباشرة بعد هذه الدالة.
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
-- "خطوة للخارج": تابع التنفيذ حتى نهاية الدالة الحالية ، زره السريع `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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
هناك العديد من الخيارات في أدوات المطورين أكثر من تلك المغطاة هنا. الدليل الكامل في .
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..38daa1530 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/).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
تتكامل معظم أدوات فحص الكود مع العديد من محررات الأكواد الشهيرة: ما عليك سوى تمكين الاضافة )(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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
كما أن بعض بيئة تطوير متكاملة (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..d741b14b8 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 .
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
لماذا تحل المهمة بهذه الطريقة؟
: ما هو مكتوب مهم. لكن ما هو * غير * مكتوب قد يكون أكثر أهمية لفهم ما يحدث. لماذا يتم حل المهمة بهذه الطريقة بالضبط؟ الكود لا يعطي إجابة.
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..641309e15 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?
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
عند كتابة دالة، يمكننا تخيل ما يجب أن تقوم به: ما هي المعاملات التي تعطي نتائج معينة. يمكننا فحص الدالة أثناء التطوير من خلال تشغيلها وموازنة مخرجاتها مع ما هو متوقع. مثلا يمكننا القيام بذلك في الطرفية.
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
`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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
إذا، تُعد عملية التطوير تكرارية. نكتب الوصف، ننفذه، نتأكد من اجتياز التنفيذ للفحص، ثم نكتب المزيد من الاختبارات، نتأكد من صحة عملها. حتى نحصل على تنفيذ صحيح مع اختباراته في الأخير.
لنُجرب تدفق التطوير هذا على حالتنا العملية.
+<<<<<<< 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).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## المواصفات أثناء التنفيذ
سنستخدم في هذا الشرح مكاتب جافا سكريبت التالية للاختبار:
+<<<<<<< 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
تُعد هذه المكاتب مفيدة للاختبار في كل من المتصفح والخادم. سنأخذ بعين الاعتبار هنا جهة المتصفح. صفحة 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/)
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
لذا، يجب أن نضيف بعض الأسطر للدالة 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..3091a75e5 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/).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
لذا فمن الشائع تمامًا أن يقوم المحرك بتطبيق الجزء القياسي فقط.
+<<<<<<< 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).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
من ناحية أخرى، كيف يمكننا جعل شفرتنا الحديثة تعمل على محركات أقدم لا تفهم الميزات الحديثة بعد؟
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
في هذه الحالة، يقوم المحوّل اللغوي بتحليل الشفرة وإعادة كتابة `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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## البوليفيلز
قد تشمل الميزات اللغوية الجديدة لغة البرمجةليست مجرد بنى بناء لغوية وعوامل تجميع، بل يمكن أيضًا أن تشمل وظائف مدمجة.
+<<<<<<< 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
في بعض محركات 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
+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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
ومن المعروف أن جوجل كروم هو الأكثر تحديثًا بالنسبة لميزات اللغة، جرب استخدامه إذا فشل تطبيق تعليمي. ومع ذلك، يعمل معظم تطبيقات التعليمات البرمجية مع أي متصفح حديث.
diff --git a/1-js/04-object-basics/01-object/article.md b/1-js/04-object-basics/01-object/article.md
index 2834171ad..19c7329df 100644
--- a/1-js/04-object-basics/01-object/article.md
+++ b/1-js/04-object-basics/01-object/article.md
@@ -44,7 +44,11 @@ let user = { // an object كائن

+<<<<<<< HEAD
يمكننا إضافة، وحذف، وقراءة الملفات من الخزانة في أي وقت.
+=======
+We can add, remove and read files from it at any time.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
يمكن الوصول إلى قيم الخاصيات باستخدام الصيغة النُقَطية (dot notation):
@@ -62,7 +66,11 @@ user.isAdmin = true;

+<<<<<<< HEAD
يمكننا استخدام المُعامِل `delete` لحذف خاصية:
+=======
+To remove a property, we can use the `delete` operator:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
delete user.age;
@@ -225,13 +233,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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
لذلك، معظم الوقت، حينما يكون اسم خاصية معروفا أو غير مركب، تستخدم الصيغة النُقطية. وإذا أردنا شيئاً أكثر تعقيدا، ننتقل إلى استخدام الأقواس المربعة.
## اختصار قيمة الخاصية (Property value shorthand)
+<<<<<<< HEAD
في الشيفرة الحقيقية، غالبًا ما نستخدم المتغيرات الموجودة بصفتها قيَمًا لأسماء الخصائص.
+=======
+In real code, we often use existing variables as values for property names.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
مثلاً:
@@ -276,7 +292,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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
لكن بالنسبة لخاصية في كائن، لا توجد مثل هذه القيود:
@@ -351,7 +371,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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js run
let user = { age: 30 };
@@ -381,7 +405,7 @@ alert( "test" in obj ); // true, الخاصية موجودة بالفعل!
مواقف مثل هذه تحدث نادراً، لأن `undefined` لا ينبغي تعيينها بشكل ذاتي. عادة ما نستخدم `null` للقيم غير المعروفة أو الفارغة. لذا معامل `in` يعتبر ضيفاً غريباً في الشيفرة.
-## The "for..in" loop
+## The "for..in" loop [#forin]
للمرور على كل مفاتيح الكائن، يوجد شكل خاص آخر للحلقة loop: `for..in`. هذه الحلقة مختلفة تمامًا عما درسناه سابقًا، أي الحلقة `for(;;)`.
@@ -438,7 +462,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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
لكن إذا قمنا بتشغيل الكود, فإننا نرى صورة مختلفة تماماً:
@@ -450,6 +478,7 @@ for (let code in codes) {
````smart header="خصائص عددية؟ ما هذا؟"
"الخصائص الرقمية integer property" مصطلح يعني هنا نصًا يمكن تحويله من وإلى عدد دون أن يتغير.
+<<<<<<< HEAD
لذا, "49" هو اسم خاصية عددي, لأنه عند تحويله إلى عدد وإرجاعه لنص, يبقى كما هو. لكن "+49" و "1.2" are ليسا كذلك:
```js run
@@ -457,6 +486,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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
````
@@ -505,9 +544,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]`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
معاملات إضافية 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..312e5405d 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
عندما نقوم بإجراء أي عمليات على الكائن، مثل الوصول إلى خاصية `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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
على سبيل المثال:
@@ -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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
الكائنات تتم تعيينها ونسخها بالمرجع. وبمعنى آخر، يخزن المتغير ليس "قيمة الكائن" ولكن "مرجع" (عنوان في الذاكرة) للقيمة. لذلك، عند نسخ هذا المتغير أو تمريره كوسيط لدالة، يتم نسخ هذا المرجع، وليس الكائن نفسه.
كل العمليات التي تتم بواسطة النسخة (مثل إضافة وحذف الخواص) تحدث على نفس الكائن.
+<<<<<<< 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).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..7fcd773b1 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## الكائنات المترابطة
@@ -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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b

@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
تلك هي المبادئ التي يعمل علي اساسها جامع القمامة. محرك ال 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
- **مجموعة الأجيال** -- -- يتم تقسيم الكائنات الي مجموعتين "الجديدة", "القديمة", الكثير من الكائنات يتم انشائها و تؤدي وظيفتها و تموت بسرعة, فيمكن التخلص منها بسرعة. اما الكائنات التي تعيش لفترة طوية تصبح "قديمة" و لا يتم التحقق منها و ازالتها بنفس الكثافة.
- **المجموعة المتزايدة** --في حالة وجود العديد من الكائنات, و حاولنا المرور ووضع علامة علي الكائن كله مرة واحدة, سيستهلك هذا بعضا من الوقت مما قد يؤدي الي بعض التأخير في عملية التنفيذ, لذلك يحاول جامع القمامة تقسيم نفسه الي اجزاء, كل الأجزاء يتم استخدامها وحدها واحدة تلو الأخري, مما قد يتطلب المزيد من الادارة لمتابعة التغييرات و تسجيلها, و لكن تأخيرات عديدة صغيرة افضل من تأخير واحد كبير.
+<<<<<<< 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
هنالك العديد من التحسينات في خوارزميات جامع القمامة. و علي قدر ما اود ان اشرحها هنا,يجب ان نتوقف و ذلك لأن المحركات الختلفة تتبني طرق و حلول مختلفة و الأهم من ذلك ان الأشياء تتغير بتتطور المحركات, لذا ادرس أكثر "مقدما" فبدون الحاجة الحقيقية لمعرفتها فهي لا تستحق العناء الا ان كنت و بالطبع تمتلك الشغف للمعرفة فالروابط بالأسفل ستساعدك بالتأكيد.
## الملخص
+<<<<<<< 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..4179f301e 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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..3efac2ead 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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..b5126ef54 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
من المتعارف أن الدوال تحتاج للوصول إلى المعلومات المخزنة في الكائن لِتنفذ عملها. مثلًا، قد تحتاج الشيفرة التي بداخل `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..03194d1a2 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## الدالة البانية
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
````
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`:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
بالمناسبة، يمكننا حذف أقواس `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..2e1923c90 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"
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
-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..85a41d3f8 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
كلمة رمز فى الإنجليزيه تعنى معَرٌِف فريد من نوعه أى لا شئ مماثل له
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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
على سبيل المثال, هذان الرمزان لهما نفس الوصف -- ولكنهما غير متساويين:
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
على سبيل المثال, هذا الكود سيؤدى إلى ظهور خطأ:
@@ -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:
+
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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:
+
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
على سبيل المثال, إذا كنا نعمل على كائن
`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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
لذلك هذا البرنامج يمكنه أن ينشئ
`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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
على النقيض تماما فإن
[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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
### 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)`:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
على سبيل المثال:
@@ -258,7 +318,11 @@ alert(Symbol.keyFor(sym2)); // id
الداله `Symbol.keyFor` عندما تعمل تقوم باستخدام مكان تسجيل الرموز العام للبحث عن إسم للرمز, ولذلك فإنها لا تعمل إلا مع الرموز العامه. فإذا كان الرمز غير عام فلن تستطيع إيجاده وستقوم بإرجاع `undefined`.
+<<<<<<< HEAD
يقال بأن كل رمز يملك الخاصيه `description`.
+=======
+That said, all symbols have the `description` property.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
على سبيل المثال:
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
إذا كنا نريد أن نضيف خاصيه إلى كائن لا ينتمى إلى هذا الكود بل إلى برنامج آخر أو مكتبه، فعندئذ يمكننا إنشاء رمز واستخدامه كخاصيه. والخاصيه من نوع الرمز لا تظهر فى التكرار `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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..245933c76 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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
-## 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):
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
`"النص"`
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
- 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
المقارنه باستخدام علامات الأكبر من أو الأصغر من مثل `<` `>`، يمكنها التعامل مع الأرقام والنصوص أيضا ولكنها مع ذلك تستخدم التحويل إلى رقم وليس الطريقه الافتراضيه، وهذا لأسباب متأصله 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## 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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
أى كائن يمتلك افتراضيا الدالتين `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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
على سبيل المثال، فإن الكائن `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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
هناك شئ مهم يجب أن تعرفه وهو أن كل طرق التحويل إلى قيم مفرده لا يجب بالضروره أن تقوم بإرجاع نفس نوع القيمه المفرده المحوَّله إليه.
+<<<<<<< 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"`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
الأمر الوحيد الذى يمكن ضمانه والإلزامى هو أن هذه الدوال يجب أن تقوم بإرجاع يمة مفردة لا كائنًا.
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
## التحويلات الإضافيه
كما نعرف بالفعل أن الكثير من العلامات والدوال تقوم بتحويل الأنواع, مثال على ذلك علامة `*` تقوم بتحويل العاملين إلى أرقام.
+<<<<<<< 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
يوضح المصدر أى عملية تستخدم أى طريقه. وهناك القليل من العمليات التي
"لا تعلم ما نوع العامل الذي ستستقبله"
وتستخدم `"الطريقه الإفتراضيه"`. وعادةً ما يتم استخدام `"الطريقة الإفتراضيه"` مع الكائنات الموجوده بالفعل كما يتم التعامل مع `"الأرقام"`, ولذلك عمليا فإن الطريقتين الأخيرتين يمكن ضمهما معًا.
+<<<<<<< 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..c436c6fa1 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?
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..0d407c085 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
إن الحل يبدو غريبا بعض الشيء، ولكن ها هو:
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
على سبيل المثال
, هنالك 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:
+
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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..c347dfb57 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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
diff --git a/1-js/05-data-types/02-number/article.md b/1-js/05-data-types/02-number/article.md
index 0198ff2ee..850b5d4b2 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 .
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## طرق أخرى لكتابة عدد
@@ -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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
بمعنى آخر، وجود رقم سالب بعد `"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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
### الأعداد الست عشرية، والثنائية والثمانية
@@ -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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
حالات الاستخدام الشائعة:
+<<<<<<< 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)`.
+
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
## 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` |
+
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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;
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
مثلًا، لتقريب الرقم إلى الخانة الثانية بعد الفاصلة العشرية، يمكننا ضرب العدد في `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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
````
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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
لاحظ أن مخرجات التابع `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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
يكون التابع `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)).
+```
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## 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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
لكتابة أعداد كبيرة:
- أضِف `"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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..373ba263c 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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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..7939b4b7b 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
-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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
| 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
@@ -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).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## طول النص
تحمل الخاصية `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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
## الوصول إلى محارف سلسلة
+<<<<<<< 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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js run
let str = `Hello`;
+<<<<<<< HEAD
alert( str[1000] ); // undefined
alert( str.charAt(1000) ); // '' (سلسلة نصية فارغ)
+=======
+alert( str[-2] ); // undefined
+alert( str.at(-2) ); // l
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
يمكننا أيضا التنقل خلال جميع محارف سلسلة باستخدام `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` (ستجدها في الأسفل).
+=======
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
### 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).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
مثلًا:
@@ -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` |
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
+
+
+<<<<<<< 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
## موازنة النصوص
@@ -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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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)
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
لنرَ الآن الأحرف ذات الرموز `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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
### 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/).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
- يُرجِع قيمة سالبة إن كان `str` أصغر من `str2`.
- يُرجِع قيمة موجبة إن كان `str` أكبر من `str2`.
@@ -555,6 +656,7 @@ mdn:js/String/localeCompare
في الحقيقة، لهذه الدالة مُعامِلين إضافيين كما في [توثيقها على MDN](mdn:js/String/localeCompare)، إذ يسمح هذان المُعاملان بتحديد اللغة (تؤخذ من بيئة العمل تلقائيًا، ويعتمد ترتيب الأحرف على اللغة) بالإضافة إلى إعداد قواعد أخرى مثل الحساسية تجاه حالة الأحرف، أو ما إن كان يجب معاملة `"a"` و `"á"` بالطريقة نفسها ...الخ.
+<<<<<<< HEAD
## ما خلف الستار، يونيكود
```warn header="**معلومات متقدمة**"
@@ -667,11 +769,13 @@ alert( "S\u0307\u0323".normalize() == "\u1e68" ); // true
إن أردت تعلم المزيد عن قواعد التوحيد واختلافاتها - فستجدها في ملحق معايير اليونيكود: [نماذج توحيد ترميز اليونيكود](http://www.unicode.org/reports/tr15/), لكن للأغراض العملية المتعارفة فالمعلومات السابقة تفي بالغرض.
## المُلخص
+=======
+## Summary
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
- 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 .
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..0b50a0d38 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
دعنا نسير في المصفوفة ونحتفظ بالمجموع الجزئي الحالي للعناصر في المتغير `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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..0bb85a7d6 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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
المصفوفه في العمليه :
```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..5726c8ed1 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]`.
+
+Although, 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).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
**الأساليب التي تعمل مع نهاية المصفوفه:**
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
`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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
إذا تم استدعاء `مصفوفه جديده` باستخدام وسيله واحدة عبارة عن رقم ، فإنه ينشئ مصفوفة * بدون عناصر ، ولكن بالطول المحدد *.
+<<<<<<< HEAD
دعونا نرى كيف يمكن للمرء أن يطلق النار على قدمه:
+=======
+Let's see how one can shoot themselves in the foot:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## مصفوفات متعدده الأبعاد
@@ -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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
## التحويل إلي نص
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
- الخاصية `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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
- `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..42c5bb4d4 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:... }`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
اكتب دالة `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..491d925bc 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## إضافة العناصر وإزالتها
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
لهذا السبب علينا استعمال توابِع خاصّة لذلك.
-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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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`:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
صياغته هي:
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
});
```
@@ -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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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)
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
+```
+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?
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
هنا يمكننا استغلال التابِع 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
نرى في هذا المثال مصفوفة من المستخدمين، لكلّ مستخدم حقلان 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
يمكنك ملاحظة بأنّا في المثال مرّرنا للتابِع 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
+```
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
### الترشيح filter
@@ -380,6 +481,11 @@ alert(arr); // *!*1, 15, 2*/!*
على الدالة موازنة قيمتين اثنتين (أيًا كانتا) وإعادة الناتج:
+<<<<<<< HEAD
+=======
+The function should compare two arbitrary values and return:
+
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
هذه الصياغة الكاملة لهذه التوابِع:
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
- `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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
* 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
انظر من خلال ورقة الغش فقط لتكون على دراية بها. ثم حل مهام هذا الفصل للممارسة ، بحيث يكون لديك خبرة في أساليب الصفيف.
diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md
index c27c0f771..e95ed5c7b 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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
على سبيل المثال، فإن الكائن `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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
// تربيع كل رقم
let arr = Array.from(range, (num) => num * num);
@@ -279,7 +301,11 @@ for (let char of str) {
alert(chars);
```
+<<<<<<< HEAD
...ولكن هذا أقصر.
+=======
+...But it is shorter.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
حتى أنه يمكننا أن نبنى دالة `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..759329cd8 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
هذه توابِعها وخاصياتها:
+<<<<<<< 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
إليك المثال الآتي:
@@ -101,16 +115,26 @@ map.set('1', 'str1')
```
+<<<<<<< HEAD
## المرور على خارطة
هناك ثلاث طرائق للمرور على عناصر `Map` وتطبيق عملية عليها:
- `map.keys()` -- يُعيد مُتعدَّدًا للمفاتيح،
- `map.values()` -- يُعيد مُتعدَّدًا للقيم،
- `map.entries()` -- يُعيد مُتعدَّدًا للمدخلات `[key, value]`، وهي التي تستعملها `for..of` مبدئيًا.
+=======
+## Iteration over Map
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
مثال:
+<<<<<<< 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
ولهذا يمكن أن نصنع خارطة من كائن بهذه الطريقة:
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## الطقم `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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
الأطقم (`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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## المرور على طقم
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
كما تدعم الأطقم نفس التوابِع التي تدعمها الخارطة للتعامل مع المُتعدَّدات:
+<<<<<<< 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## ملخص
+<<<<<<< HEAD
+=======
+[`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) -- is a collection of keyed values.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
الخارطة `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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..510148694 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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## 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*.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..4f15fceeb 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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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])
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
);
*/!*
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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..0c52741d1 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.
+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..d9041a655 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
يجب أن يكون العام `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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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 .
+```
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
يمكنك أن تقرأ بعض المقالات الرائعة حول 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..7ba25962d 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
تحتوى جافا سكريبت على دوال للتعامل مع الكائن 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
إن الكائن 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..7b5d378c9 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..18d276d9c 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
نحن لا نمتلك طرييقة للحصول علي القيمة الأخيرة في القائمة ولا نستطيع العودة للخلف.
diff --git a/1-js/06-advanced-functions/01-recursion/article.md b/1-js/06-advanced-functions/01-recursion/article.md
index ea5da247c..905d9e1d5 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
الدالة المتكررة "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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
مثلاً القائمة المتصلة يمكن تعريفها علي أنها هيكل بيانات تتكون من شئ 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..ce4ba461c 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
يمكن تضمين بقية المُعاملات في تعريف الدالة باستعمال الثلاث نقاط `...` ثمّ اسم المصفوفة التي ستحتويهم. تعني تلك النقط حرفيًا «اجمع المُعاملات الباقية في مصفوفة».
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..b5508d6b2 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.
+
+ 
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
السؤال هو لماذا تظهر لجميع الدوال نفس القيمة، وهي الرقم `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..6908376fa 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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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..fa5a44f91 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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
*/!*
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..3fedcb6fc 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?
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
دعنا نوسع معرفتنا لفهم هذه السيناريوهات والسيناريوهات الأكثر تعقيدًا.
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## البيئات المعجمية
diff --git a/1-js/06-advanced-functions/04-var/article.md b/1-js/06-advanced-functions/04-var/article.md
index 8b01fb9b0..1092ea95d 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
ذكرنا في أوائل الفصول حين تكلمنا عن [المتغيرات](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..1b30b5eb4 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..6094f638f 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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
إليك هذه الشيفرة التي تستدعي 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## setInterval
@@ -235,7 +243,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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
````
## جدولة setTimeout بتأخير صفر
@@ -258,8 +270,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.".
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
لنرى ما يعني ذلك بهذا المثال أسفله. يُعيد استدعاء setTimeout جدولة نفسه بمدّة تأخير تساوي صفر، ويتذكّر كل استدعاء الوقت الفعلي بينه وبين آخر استدعاء في مصفوفة times. ولكن، ما هي التأخيرات الفعلية؟ لنرى بأعيننا:
@@ -297,7 +314,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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
- المعالج مُثقل بالعمليات.
- المتصفّح يعمل في الخلفية.
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..66740f4b2 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`:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
- يُتيح لنا مُعامل التوزيع `...` تمرير _المُتعدَّد_ `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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
يُدى تمرير كافة المُعاملات (مع السياق) من دالة إلى أخرى _بتمرير الاستدعاء_.
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..de05d1852 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
كما أنّ المُعاملات كلّها تُمرّر إلى دالة `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)
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
**تابِع مفيد: `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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
````
## الدوال الجزئية
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..19f87fca9 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
و صياغتها تكون كالآتي:
@@ -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.
+```
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
````
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
فمثلاً, `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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
// 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.**
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
و صياغتها تكون كالآتي:
@@ -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).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
بدمجه مع `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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## إغلاق الكائنات على المستوى العام
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
كما أنّ هناك توابِع أخرى تفحص تلك المزايا:
+<<<<<<< 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
أمّا على أرض الواقع، فنادرًا ما نستعمل تلك الطرق.
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..4d3f3e390 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`:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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..ec4db1941 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
بعدها متى ما حاولت التعليمة `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]]`"
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
بهذا يمكننا ترشيح الخاصيات الموروثة (ونتعامل معها على حدة):
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..8acaffdc0 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## 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..8a05ebe30 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
diff --git a/1-js/08-prototypes/04-prototype-methods/article.md b/1-js/08-prototypes/04-prototype-methods/article.md
index 82871b94e..a5d4b48ce 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).
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
-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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
عل ىسبيل المثال:
@@ -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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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)
+);
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
هذا الإستدعاء يقوم بإنشاء نسخه طبق الأصل من الكائن `obj` بما فيه من خصائص سواءًا كانت معدودة (enumerable) أم لا وكذلك الجالبات والمغيرات (getters & setters) -- كل شيئ وبالخاصية `[[Prototype]]` الصحيحة.
+<<<<<<< HEAD
## نبذة من التاريخ
إذا عددنا كل الطرق للتحكم فى `[[Prototype]]`، فهناك الكثير! توجد الكثير من الطرق للقيام بنفس الشيئ!
لماذا؟
+=======
+
+## Brief history
+
+There're so many ways to manage `[[Prototype]]`. How did that happen? Why?
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
هذا لأسباب تاريخية متأصّلة.
+<<<<<<< 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
ولكننا لم نقصد أن نفعل ذلك، أليس كذلك؟ نريد أن نخزن خاصية بقيمتها واسم الخاصية `"__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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
وأسوأ من ذلك -- لا يفكر المطورون عادة عن إمكانية كهذه أبدًا. وهذا يجعل الخطأ صعب الملاحظة ويمكن أن يتحول إلى ثغرة خصوصًا إذا كان البرنامج يعمل على السيرفر.
+<<<<<<< HEAD
ويمكن أن تحدث أيضًا أشياء غير متوقعة عند وضع قيمة للدالة `toString` والتى هي دالة بطبيعتها وكذلك لدوال أخرى.
+=======
+Unexpected things also may happen when assigning to `obj.toString`, as it's a built-in object method.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
كيف يمكننا تجنب هذه المشكلة؟
+<<<<<<< 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`:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b

@@ -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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
-- [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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
+
+ - [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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
diff --git a/1-js/09-classes/01-class/article.md b/1-js/09-classes/01-class/article.md
index 19711656e..804f8da3f 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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
تقوم اللغة بالتحقق من هذه الخاصية في أماكن متنوعة. على سبيل المثال ، على عكس الوظيفة العادية ، يجب أن يتم استدعاؤها بـ `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..53b8fa825 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
توفر الفصول كلمة رئيسية `` فائقة '' لذلك.
@@ -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:
+
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```js
class Rabbit extends Animal {
stop() {
@@ -177,9 +186,13 @@ setTimeout(function() { super.stop() }, 1000);
```
````
+<<<<<<< HEAD
## تجاوز constructor
مع المنشئين يصبح الأمر صعبًا بعض الشيء.
+=======
+## Overriding constructor
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
حتى الآن ، لم يكن لدى "الأرنب" "مُنشئ" خاص به.
@@ -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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
- 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]]
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
إنه يتعلق بالآليات الداخلية الكامنة وراء الميراث و "السوبر".
``
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..05a755132 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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
كما نعلم ، فإن الصيغة "الممتدة" تضع نموذجين أوليين:
1. بين "النموذج" لوظائف المنشئ (للطرق).
2. بين وظائف المنشئ أنفسهم (للأساليب الثابتة).
+<<<<<<< HEAD
في حالتنا ، تعني كلمة "أرنب يمتد الكائن" ما يلي:
+=======
+In the case of `class Rabbit extends Object` it means:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
ها هي الصورة:
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..8e87caa01 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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
1. إنشاء بواسطة معلمات معينة (`العنوان` ،` التاريخ` وما إلى ذلك).
2. إنشاء مقال فارغ بتاريخ اليوم.
@@ -72,7 +94,11 @@ alert( articles[0].title ); // CSS
يمكن تنفيذ الطريقة الأولى من قبل المنشئ. وللثاني يمكننا عمل طريقة ثابتة للفئة.
+<<<<<<< HEAD
مثل `Article.createTodays()` هنا:
+=======
+Such as `Article.createTodays()` here:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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});
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
+```
+
+````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..317a81072 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`:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```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..cf252006c 100644
--- a/1-js/09-classes/06-instanceof/article.md
+++ b/1-js/09-classes/06-instanceof/article.md
@@ -87,9 +87,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!)
+ */!*
+ ```
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..40a0b5364 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]]`.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
## 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..7d9a7348c 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 .
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
يعملون على هذا النحو:
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..64390d9d1 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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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
+*!*
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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..7a7bde808 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.
+```
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
### تقييم شيفرة الوحدة لمرة واحدة فقط
+<<<<<<< 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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
أولًا، لو كان لشيفرة الوحدة التي ستُنفّذ أيّ تأثيرات (مثل عرض رسالة أو ما شابه)، فاستيرادها أكثر من مرّة سيشغّل ذلك التأثير مرة واحدة، وهي أول مرة فقط:
@@ -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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
لنقل بأنّ هناك وحدة تُصدّر كائنًا:
@@ -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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
// 📁 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`:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
// 📁 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';
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
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:
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
```
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.
+>>>>>>> 540d753e90789205fc6e75c502f68382c87dea9b
### سكربتات الوحدات مؤجلة
@@ -244,9 +353,13 @@ html run height=0
أي وبعبارة أخرى:
+<<<<<<< HEAD
- تنزيل السكربتات المعتمدة على الوحدات الخارجية `
+