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/1-js/01-getting-started/4-devtools/article.md b/1-js/01-getting-started/4-devtools/article.md
index 4ba5c0a35..2210674ca 100644
--- a/1-js/01-getting-started/4-devtools/article.md
+++ b/1-js/01-getting-started/4-devtools/article.md
@@ -22,7 +22,7 @@
ÐÑÑ Ñак вÑдобÑажаÑÑÑÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° в конÑолÑ:
-
+
ТоÑний виглÑд ÑнÑÑÑÑменÑÑв ÑозÑобника може вÑдÑÑзнÑÑиÑÑ Ð² залежноÑÑÑ Ð²Ñд ваÑÐ¾Ñ Ð²ÐµÑÑÑÑ Chrome, а Ñакож налаÑÑÑÐ²Ð°Ð½Ð½Ñ Ð¼Ð¾Ð²Ð¸.
@@ -49,7 +49,11 @@
Safari (ÑÑандаÑÑний бÑаÑÐ·ÐµÑ Ñ macOS, не пÑдÑÑимÑÑÑÑÑÑ Windows/Linux) Ð¼Ð°Ñ ÑÐ²Ð¾Ñ Ð½ÑанÑи. СпоÑаÑÐºÑ Ð½Ð°Ð¼ поÑÑÑбно ÑвÑмкнÑÑи Ð¼ÐµÐ½Ñ "РозÑобка".
+<<<<<<< HEAD
ÐÑдкÑийÑе ÐаÑамеÑÑи Ñа пеÑейдÑÑÑ Ð½Ð° Ð¿Ð°Ð½ÐµÐ»Ñ "ÐкÑпеÑÑнÑ". ÐÐ½Ð¸Ð·Ñ Ð±Ñде галоÑка, ÑÐºÑ Ð½ÐµÐ¾Ð±Ñ
Ñдно вибÑаÑи:
+=======
+Open Settings and go to the "Advanced" pane. There's a checkbox at the bottom:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533

diff --git a/1-js/01-getting-started/4-devtools/chrome.webp b/1-js/01-getting-started/4-devtools/chrome.webp
new file mode 100644
index 000000000..bdf067079
Binary files /dev/null and b/1-js/01-getting-started/4-devtools/chrome.webp differ
diff --git a/1-js/01-getting-started/4-devtools/[email protected] b/1-js/01-getting-started/4-devtools/[email protected]
new file mode 100644
index 000000000..2aeca5898
Binary files /dev/null and b/1-js/01-getting-started/4-devtools/[email protected] differ
diff --git a/1-js/02-first-steps/04-variables/article.md b/1-js/02-first-steps/04-variables/article.md
index 639f68f42..a9e3a6330 100644
--- a/1-js/02-first-steps/04-variables/article.md
+++ b/1-js/02-first-steps/04-variables/article.md
@@ -88,16 +88,26 @@ let user = 'Ðван'
*!*var*/!* message = 'ÐÑивÑÑ';
```
+<<<<<<< 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 .
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
````
## ÐналогÑÑ Ð· жиÑÑÑ
Ðи легко зÑозÑмÑÑмо конÑепÑÑÑ "змÑнноÑ", ÑкÑо ÑÑвимо ÑÑ Ñ Ð²Ð¸Ð³Ð»ÑÐ´Ñ "коÑобки" Ð´Ð»Ñ Ð´Ð°Ð½Ð¸Ñ
з ÑнÑкалÑÐ½Ð¾Ñ Ð½Ð°Ð·Ð²Ð¾Ñ Ð½Ð° наклейÑÑ.
+<<<<<<< HEAD
ÐапÑиклад, змÑÐ½Ð½Ñ `message` можна ÑÑвиÑи Ñк коÑÐ¾Ð±ÐºÑ Ð· напиÑом `"ÐовÑдомленнÑ"` Ð·Ñ Ð·Ð½Ð°ÑеннÑм `"ÐÑивÑÑ!"` вÑеÑединÑ:
+=======
+For instance, the variable `message` can be imagined as a box labelled `"message"` with the value `"Hello!"` in it:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533

@@ -197,15 +207,24 @@ let my-name; // деÑÑÑ '-' недопÑÑÑимий в ÑменÑ
ÐмÑÐ½Ð½Ñ Ð· Ñменами `apple` Ñ `APPLE` -- Ñе Ð´Ð²Ñ ÑÑÐ·Ð½Ñ Ð·Ð¼ÑннÑ.
```
+<<<<<<< HEAD
````smart header="ÐелаÑинÑÑÐºÑ Ð±Ñкви дозволенÑ, але не ÑекомендÑÑÑÑÑÑ"
Ðожна викоÑиÑÑовÑваÑи бÑдÑ-ÑÐºÑ Ð¼Ð¾Ð²Ñ, вклÑÑно з киÑилиÑÐµÑ Ð°Ð±Ð¾ навÑÑÑ ÑÑÑоглÑÑами, напÑиклад:
+=======
+````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:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js
let назва = '...';
let æ = '...';
```
+<<<<<<< HEAD
ТеÑ
нÑÑно ÑÑÑ Ð½ÐµÐ¼Ð°Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ¸. Ð¢Ð°ÐºÑ Ñмена дозволенÑ, пÑоÑе Ñ Ð¼ÑжнаÑодна ÑÑадиÑÑÑ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑваÑи англÑйÑÑÐºÑ Ð¼Ð¾Ð²Ñ Ð² ÑменаÑ
змÑнниÑ
(напÑиклад, `yaLyublyuUkrainu` => `iLoveUkraine`). ÐавÑÑÑ ÑкÑо ми пиÑемо маленÑкий ÑкÑипÑ, Ñ Ð½Ñого може бÑÑи ÑÑивале жиÑÑÑ Ð¿Ð¾Ð¿ÐµÑедÑ. Ðожливо, лÑдÑм з ÑнÑиÑ
кÑаÑн колиÑÑ Ð´Ð¾Ð²ÐµÐ´ÐµÑÑÑÑ Ð¿ÑоÑиÑаÑи його.
+=======
+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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
````
````warn header="ÐаÑезеÑÐ²Ð¾Ð²Ð°Ð½Ñ Ñлова"
@@ -260,11 +279,19 @@ 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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
### ÐонÑÑанÑи в веÑÑ
нÑÐ¾Ð¼Ñ ÑегÑÑÑÑÑ
+<<<<<<< HEAD
ШиÑоко поÑиÑена пÑакÑика викоÑиÑÑÐ°Ð½Ð½Ñ ÐºÐ¾Ð½ÑÑÐ°Ð½Ñ Ñк пÑевдонÑмÑв Ð´Ð»Ñ Ð·Ð½Ð°ÑенÑ, ÑÐºÑ Ð²Ð°Ð¶ÐºÐ¾ запамâÑÑаÑи Ñ ÑÐºÑ Ð²ÑÐ´Ð¾Ð¼Ñ Ð´Ð¾ поÑаÑÐºÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ ÑкÑипÑÑ.
+=======
+There is a widespread practice to use constants as aliases for difficult-to-remember values that are known before execution.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Ð¢Ð°ÐºÑ ÐºÐ¾Ð½ÑÑанÑи пиÑÑÑÑÑÑ Ð² веÑÑ
нÑÐ¾Ð¼Ñ ÑегÑÑÑÑÑ Ð· викоÑиÑÑаннÑм пÑдкÑеÑленÑ.
@@ -289,7 +316,11 @@ 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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐапÑиклад:
@@ -297,7 +328,11 @@ alert(color); // #FF7F00
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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐнакÑе кажÑÑи, конÑÑанÑи з великими бÑквами викоÑиÑÑовÑÑÑÑÑÑ Ñк пÑевдонÑми Ð´Ð»Ñ "жоÑÑÑко закодованиÑ
" знаÑенÑ.
@@ -307,18 +342,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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐÑÐ´Ñ Ð»Ð°Ñка, пÑидÑлÑйÑе ÑÐ°Ñ Ð½Ð° обдÑмÑÐ²Ð°Ð½Ð½Ñ Ð¿ÑавилÑного ÑÐ¼ÐµÐ½Ñ Ð´Ð»Ñ Ð·Ð¼ÑÐ½Ð½Ð¾Ñ Ð¿ÐµÑед ÑÑ Ð¾Ð³Ð¾Ð»Ð¾ÑеннÑм. РобÑÑÑ Ñак, Ñ Ð±ÑдеÑе винагоÑодженÑ.
ÐекÑлÑка Ñ
оÑоÑиÑ
пÑавил:
+<<<<<<< HEAD
- ÐикоÑиÑÑовÑйÑе Ñмена, ÑÐºÑ Ð»ÐµÐ³ÐºÐ¾ пÑоÑиÑаÑи, Ñк-Ð¾Ñ `userName` або `shoppingCart`.
- УникайÑе викоÑиÑÑÐ°Ð½Ð½Ñ Ð°Ð±ÑевÑаÑÑÑ Ð°Ð±Ð¾ коÑоÑкиÑ
Ñмен, ÑакиÑ
Ñк `a`, `b` Ñа `c`, окÑÑм ÑиÑ
випадкÑв, коли ви ÑоÑно знаÑÑе, Ñо Ñак поÑÑÑбно.
- РобÑÑÑ Ñмена макÑималÑно опиÑовими Ñ Ð»Ð°ÐºÐ¾Ð½ÑÑними. ÐапÑиклад, ÑÐ°ÐºÑ Ñмена поганÑ: `data` Ñ `value`. Ð¢Ð°ÐºÑ Ñмена нÑÑого не говоÑÑÑÑ. ÐÑ
можна викоÑиÑÑовÑваÑи лиÑе ÑодÑ, коли з конÑекÑÑÑ Ð¾Ñевидно, на ÑÐºÑ Ð´Ð°Ð½Ñ Ð°Ð±Ð¾ знаÑÐµÐ½Ð½Ñ Ð¿Ð¾ÑилаÑÑÑÑÑ Ð·Ð¼Ñнна.
- ÐогоджÑйÑе з ваÑÐ¾Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ñ (Ñа з Ñамим ÑобоÑ), ÑÐºÑ ÑеÑмÑни бÑдÑÑÑ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑваÑиÑÑ Ñ Ð¿ÑоÑкÑÑ. ЯкÑо вÑдвÑдÑÐ²Ð°Ñ ÑайÑÑ Ð½Ð°Ð·Ð¸Ð²Ð°ÑÑÑÑÑ "user", ÑÐ¾Ð´Ñ Ð¼Ð¸ маÑмо даваÑи вÑдповÑÐ´Ð½Ñ Ñмена ÑнÑим повâÑзаним змÑнним: `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`.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐвÑÑиÑÑ Ð»ÐµÐ³ÐºÐ¾? Це дÑйÑно Ñак, пÑоÑе на пÑакÑиÑÑ ÑÑвоÑÐµÐ½Ð½Ñ Ð·ÑозÑмÑлиÑ
Ñ ÐºÐ¾ÑоÑкиÑ
Ñмен -- ÑÑдкÑÑÑÑ. ÐÑйÑе.
diff --git a/1-js/02-first-steps/05-types/article.md b/1-js/02-first-steps/05-types/article.md
index e5a4f02b3..c4804d00c 100644
--- a/1-js/02-first-steps/05-types/article.md
+++ b/1-js/02-first-steps/05-types/article.md
@@ -94,6 +94,7 @@ const bigInt = 1234567890123456789012345678901234567890n;
ЧеÑез Ñе, Ñо Ñип `BigInt` ÑÑдко викоÑиÑÑовÑÑÑÑÑÑ, ми не ÑозглÑдаÑимемо його в ÑÑÐ¾Ð¼Ñ ÑоздÑлÑ, пÑоÑе ми винеÑли його в окÑемий ÑоздÑл . ÐÑоÑиÑайÑе його, ÑкÑо вам поÑÑÑÐ±Ð½Ñ ÑÐ°ÐºÑ Ð²ÐµÐ»Ð¸ÐºÑ ÑиÑла.
+<<<<<<< HEAD
```smart header="ÐÑоблеми Ñз ÑÑмÑÑнÑÑÑÑ"
ЦÑÑÑ Ð¼Ð¸ÑÑ, пÑдÑÑимка ÑÐ¸Ð¿Ñ `BigInt` Ñ Ð² оÑÑаннÑÑ
веÑÑÑÑÑ
Firefox/Chrome/Edge/Safari, але не в IE.
@@ -102,6 +103,9 @@ const bigInt = 1234567890123456789012345678901234567890n;
Ðа ÑайÑÑ *MDN* Ñ [ÑаблиÑÑ ÑÑмÑÑноÑÑÑ](https://developer.mozilla.org/uk/docs/Web/JavaScript/Reference/Global_Objects/BigInt#СÑмÑÑнÑÑÑÑ_з_веб-пеÑеглÑдаÑами), де показано, ÑÐºÑ Ð²ÐµÑÑÑÑ Ð±ÑаÑзеÑÑв пÑдÑÑимÑÑÑÑ Ñип `BigInt`.
## Ð Ñдок (string)
+=======
+## String
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Ð Ñдок Ñ JavaScript Ð¼Ð°Ñ Ð±ÑÑи оÑоÑений лапками.
diff --git a/1-js/02-first-steps/09-comparison/article.md b/1-js/02-first-steps/09-comparison/article.md
index 585ea4ba3..a27b87c5e 100644
--- a/1-js/02-first-steps/09-comparison/article.md
+++ b/1-js/02-first-steps/09-comparison/article.md
@@ -209,8 +209,16 @@ alert( undefined == 0 ); // false (3)
## ÐÑдÑÑмки
+<<<<<<< HEAD
- ÐпеÑаÑоÑи поÑÑвнÑÐ½Ð½Ñ Ð¿Ð¾Ð²ÐµÑÑаÑÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ Ð»Ð¾Ð³ÑÑного ÑипÑ.
- Ð Ñдки поÑÑвнÑÑÑÑÑÑ Ð¿Ð¾ÑимволÑно в лекÑикогÑаÑÑÑÐ½Ð¾Ð¼Ñ Ð¿Ð¾ÑÑдкÑ.
- ÐнаÑÐµÐ½Ð½Ñ ÑÑзниÑ
ÑипÑв пÑд ÑÐ°Ñ Ð¿Ð¾ÑÑвнÑÐ½Ð½Ñ ÐºÐ¾Ð½Ð²ÐµÑÑÑÑÑÑÑÑ Ð² ÑиÑла. ÐинÑÑками Ñ Ð¿Ð¾ÑÑвнÑÐ½Ð½Ñ Ð·Ð° Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ Ð¾Ð¿ÐµÑаÑоÑÑв ÑÑÑÐ¾Ð³Ð¾Ñ ÑÑвноÑÑÑ/неÑÑвноÑÑÑ.
- ÐнаÑÐµÐ½Ð½Ñ `null` Ñ `undefined` ÑÑÐ²Ð½Ñ `==` один Ð¾Ð´Ð½Ð¾Ð¼Ñ Ñ Ð½Ðµ ÑÑÐ²Ð½Ñ Ð±ÑдÑ-ÑÐºÐ¾Ð¼Ñ ÑнÑÐ¾Ð¼Ñ Ð·Ð½Ð°ÑеннÑ.
- ÐÑдÑÑе обеÑежнÑ, викоÑиÑÑовÑÑÑи опеÑаÑоÑи поÑÑвнÑÐ½Ð½Ñ Ð½Ð° зÑазок `>` Ñи `<` Ð·Ñ Ð·Ð¼Ñнними, ÑÐºÑ Ð¼Ð¾Ð¶ÑÑÑ Ð¿ÑиймаÑи знаÑÐµÐ½Ð½Ñ `null/undefined`. ХоÑоÑÐ¾Ñ ÑдеÑÑ Ð±Ñде зÑобиÑи окÑÐµÐ¼Ñ Ð¿ÐµÑевÑÑÐºÑ Ð½Ð° `null/undefined` Ð´Ð»Ñ ÑакиÑ
знаÑенÑ.
+=======
+- Comparison operators return a boolean value.
+- Strings are compared letter-by-letter in the "dictionary" order.
+- When values of different types are compared, they get converted to numbers (with the exclusion of a strict equality check).
+- The values `null` and `undefined` are equal `==` to themselves and each other, but do not equal any other value.
+- Be careful when using comparisons like `>` or `<` with variables that can occasionally be `null/undefined`. Checking for `null/undefined` separately is a good idea.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
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 8024870bc..5889942ce 100644
--- a/1-js/02-first-steps/16-function-expressions/article.md
+++ b/1-js/02-first-steps/16-function-expressions/article.md
@@ -82,7 +82,7 @@ let sayHi = function() { // (1) ÑÑвоÑиÑи
alert( "ÐÑивÑÑ" );
};
-let func = sayHi;
+let func = sayHi; //(2)
// ...
```
diff --git a/1-js/03-code-quality/06-polyfills/article.md b/1-js/03-code-quality/06-polyfills/article.md
index 5eeb93608..2189ad314 100644
--- a/1-js/03-code-quality/06-polyfills/article.md
+++ b/1-js/03-code-quality/06-polyfills/article.md
@@ -7,7 +7,11 @@
Ð¢Ð¾Ð¼Ñ Ñе ÑÑлком звиÑайна ÑиÑÑаÑÑÑ, коли лиÑе ÑаÑÑина ÑÑандаÑÑÑ ÑеалÑзована Ñ ÑÐ°Ð¼Ð¾Ð¼Ñ ÑÑÑÑÑ.
+<<<<<<< HEAD
ХоÑоÑа ÑÑоÑÑнка, Ñоб побаÑиÑи поÑоÑний ÑÑан пÑдÑÑимки ÑÑнкÑÑй мови, Ñ ÑÑÑ (вона велика, нам доведеÑÑÑÑ Ñе багаÑо вивÑаÑи).
+=======
+A good page to see the current state of support for language features is (it's big, we have a lot to study yet).
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Як пÑогÑамÑÑÑи, ми б Ñ
оÑÑли викоÑиÑÑовÑваÑи найновÑÑÑ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾ÑÑÑ. Чим бÑлÑÑе Ñ
оÑоÑиÑ
ÑеÑей â Ñим кÑаÑе!
@@ -71,9 +75,13 @@ if (!Math.trunc) { // ÑкÑо Ð½ÐµÐ¼Ð°Ñ ÑÐ°ÐºÐ¾Ñ ÑÑнкÑÑÑ
JavaScript дÑже динамÑÑна мова -- ÑкÑипÑи можÑÑÑ Ð´Ð¾Ð´Ð°Ð²Ð°Ñи Ñи оновлÑваÑи ÑÑнкÑÑÑ, навÑÑÑ ÑкÑо вони вбÑдованÑ.
+<<<<<<< HEAD
Рдва ÑÑкавиÑ
полÑÑÑла:
- [core js](https://github.com/zloirock/core-js), Ñо пÑдÑÑимÑÑ Ð±Ð°Ð³Ð°Ñо ÑÑнкÑÑонала, дозволÑÑ Ð²ÐºÐ»ÑÑаÑи лиÑе необÑ
ÑÐ´Ð½Ñ ÑÑнкÑÑÑ.
+=======
+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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
## ÐÑдÑÑмки
@@ -83,8 +91,16 @@ JavaScript дÑже динамÑÑна мова -- ÑкÑипÑи можÑÑÑ
ÐапÑиклад, пÑзнÑÑе (коли доÑÑаÑнÑо вивÑиÑе JavaScript), ви зможеÑе налаÑÑÑваÑи ÑиÑÑÐµÐ¼Ñ Ð·Ð±Ð¾ÑÑ Ð¿ÑоÑкÑÑ Ð½Ð° оÑÐ½Ð¾Ð²Ñ [webpack](https://webpack.js.org/) Ñз плагÑном [babel-loader](https://github.com/babel/babel-loader).
+<<<<<<< HEAD
ÐÑÑ Ñ
оÑоÑÑ ÑеÑÑÑÑи, де можна дÑзнаÑиÑÑ Ð¿Ð¾ÑоÑний ÑÑан пÑдÑÑимки ÑÑзного ÑÑнкÑÑоналÑ:
- - Ð´Ð»Ñ ÑиÑÑого JavaScript.
- - Ð´Ð»Ñ Ð±ÑаÑзеÑниÑ
ÑÑнкÑÑй.
+=======
+Good resources that show the current state of support for various features:
+- - for pure JavaScript.
+- - for browser-related functions.
+
+P.S. Google Chrome is usually the most up-to-date with language features, try it if a tutorial demo fails. Most tutorial demos work with any modern browser though.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
P.S. ÐазвиÑай бÑаÑÐ·ÐµÑ Google Chrome пÑдÑÑимÑÑ Ð±ÑлÑÑÑÑÑÑ Ð½Ð°Ð¹Ð½Ð¾Ð²ÑÑиÑ
ÑÑнкÑÑй мови, ÑпÑобÑйÑе його, ÑкÑо демонÑÑÑаÑÑÑ Ð½Ðµ пÑаÑÑÑ. ÐÑлÑÑÑÑÑÑ Ð´ÐµÐ¼Ð¾Ð½ÑÑÑаÑÑй пÑаÑÑÑÑÑ Ñз ÑÑÑаÑними бÑаÑзеÑами.
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 02fec1c1f..edff18927 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 @@ importance: 2
# ÐанÑÑг викликÑв
+<<<<<<< HEAD
ÐÑнÑÑ Ð¾Ð±'ÑÐºÑ `ladder`, Ñо дозволÑÑ Ð¿ÑдÑймаÑиÑÑ Ð²Ð³Ð¾ÑÑ-вниз:
+=======
+There's a `ladder` object that allows you to go up and down:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js
let ladder = {
@@ -21,7 +25,11 @@ let ladder = {
};
```
+<<<<<<< HEAD
ТепеÑ, ÑкÑо нам поÑÑÑбно зÑобиÑи кÑлÑка викликÑв поÑлÑдовно, можна зÑобиÑи Ñе Ñак:
+=======
+Now, if we need to make several calls in sequence, we can do it like this:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js
ladder.up();
@@ -32,10 +40,18 @@ ladder.down();
ladder.showStep(); // 0
```
+<<<<<<< HEAD
ÐмÑнÑÑÑ ÐºÐ¾Ð´ `up`, `down` Ñ `showStep` Ñак, Ñоб зÑобиÑи доÑÑÑпним ланÑÑг викликÑв, напÑиклад:
+=======
+Modify the code of `up`, `down`, and `showStep` to make the calls chainable, like this:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js
ladder.up().up().down().showStep().down().showStep(); // shows 1 then 0
```
+<<<<<<< HEAD
Такий пÑдÑ
Ñд ÑиÑоко викоÑиÑÑовÑÑÑÑÑÑ Ð² бÑблÑоÑекаÑ
JavaScript.
+=======
+Such an approach is widely used across JavaScript libraries.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
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 4916a24da..4cd342bdb 100644
--- a/1-js/04-object-basics/09-object-toprimitive/article.md
+++ b/1-js/04-object-basics/09-object-toprimitive/article.md
@@ -253,7 +253,11 @@ let obj = {
}
};
+<<<<<<< HEAD
alert(obj + 2); // 22 ("2" + 2), пеÑеÑвоÑÐµÐ½Ð½Ñ Ð´Ð¾ пÑимÑÑÐ¸Ð²Ñ Ð¿Ð¾Ð²ÐµÑнÑло ÑÑдок => ÐонкаÑенаÑÑÑ
+=======
+alert(obj + 2); // "22" ("2" + 2), conversion to primitive returned a string => concatenation
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```
## ÐÑдÑÑмки
diff --git a/1-js/05-data-types/02-number/article.md b/1-js/05-data-types/02-number/article.md
index 4a06296fe..a990da1e0 100644
--- a/1-js/05-data-types/02-number/article.md
+++ b/1-js/05-data-types/02-number/article.md
@@ -4,7 +4,11 @@
1. ÐвиÑÐ°Ð¹Ð½Ñ ÑиÑла в JavaScript, Ñо збеÑÑгаÑÑÑÑÑ Ñ 64-бÑÑÐ½Ð¾Ð¼Ñ ÑоÑмаÑÑ [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754), Ñакож вÑÐ´Ð¾Ð¼Ñ Ñк "подвÑÐ¹Ð½Ñ ÑоÑÐ½Ñ ÑиÑла з плаваÑÑÐ¾Ñ ÐºÐ¾Ð¼Ð¾Ñ". Це ÑиÑла, ÑÐºÑ Ð¼Ð¸ викоÑиÑÑовÑÑмо бÑлÑÑÑÑÑÑ ÑаÑÑ, Ñ Ð¿Ñо ниÑ
ми поговоÑимо в ÑÑÐ¾Ð¼Ñ ÑоздÑлÑ.
+<<<<<<< HEAD
2. ЧиÑла BigInt, Ð´Ð»Ñ Ð²ÑдобÑÐ°Ð¶ÐµÐ½Ð½Ñ ÑÑлиÑ
ÑиÑел довÑлÑÐ½Ð¾Ñ Ð´Ð¾Ð²Ð¶Ð¸Ð½Ð¸. ÐÐ½Ð¾Ð´Ñ Ð²Ð¾Ð½Ð¸ поÑÑÑбнÑ, оÑкÑлÑки звиÑайне ÑиÑло не може безпеÑно пеÑевиÑÑваÑи (253-1) або бÑÑи менÑе нÑж -(253-1), Ñк ми згадÑвали ÑанÑÑе в ÑоздÑÐ»Ñ . ÐÑкÑлÑки ÑиÑла BigInt викоÑиÑÑовÑÑÑÑÑÑ Ð² декÑлÑкоÑ
ÑпеÑÑалÑниÑ
облаÑÑÑÑ
, Ñм пÑиÑвÑÑено окÑемий ÑоздÑл .
+=======
+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 .
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
То ж ÑÑÑ Ð¼Ð¸ поговоÑимо пÑо звиÑÐ°Ð¹Ð½Ñ ÑиÑла. Ðоглибимо наÑÑ Ð·Ð½Ð°Ð½Ð½Ñ Ð¿Ñо ниÑ
.
@@ -41,7 +45,11 @@ alert( 7.3e9 ); // 7.3 мÑлÑÑÑдÑв (Ñе ж Ñаме, Ñо й 7300000000
1.23e6 === 1.23 * 1000000; // e6 ознаÑÐ°Ñ *1000000
```
+<<<<<<< HEAD
Ð¢ÐµÐ¿ÐµÑ Ð½Ð°Ð¿Ð¸Ñемо ÑоÑÑ Ð´Ñже маленÑке. ÐапÑиклад, 1 мÑкÑоÑекÑнда (одна мÑлÑйонна ÑаÑÑина ÑекÑнди):
+=======
+Now let's write something very small. Say, 1 microsecond (one-millionth of a second):
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js
let mÑs = 0.000001;
@@ -103,13 +111,23 @@ 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`.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐагалÑÐ½Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÐ¸ викоÑиÑÑÐ°Ð½Ð½Ñ Ð´Ð»Ñ ÑÑого Ñ:
+<<<<<<< HEAD
- **base=16** викоÑиÑÑовÑÑÑÑÑÑ Ð´Ð»Ñ ÑÑÑÑнадÑÑÑковиÑ
колÑоÑÑв, кодÑÐ²Ð°Ð½Ð½Ñ ÑимволÑв ÑоÑо, ÑиÑÑи можÑÑÑ Ð±ÑÑи `0..9` або `A..F`.
- **base=2** викоÑиÑÑовÑÑÑÑÑÑ Ð² оÑÐ½Ð¾Ð²Ð½Ð¾Ð¼Ñ Ð´Ð»Ñ Ð½Ð°Ð»Ð°Ð³Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ Ð±ÑÑовиÑ
опеÑаÑÑй, ÑиÑÑи можÑÑÑ Ð±ÑÑи `0` або `1`.
- **base=36** Ñ Ð¼Ð°ÐºÑималÑноÑ, ÑиÑÑи можÑÑÑ Ð±ÑÑи `0..9` або `A..Z`. ÐÐ»Ñ Ð¿Ð¾Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ Ñакого ÑиÑла в ÑкоÑÑÑ ÑиÑÐµÑ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑÑÑÑÑÑ ÑвеÑÑ Ð»Ð°ÑинÑÑкий алÑавÑÑ. ÐÑмедно, але пеÑÐµÐ²ÐµÐ´ÐµÐ½Ð½Ñ ÑиÑла в ÑÐ°ÐºÑ ÑиÑÑÐµÐ¼Ñ ÑиÑÐ»ÐµÐ½Ð½Ñ Ð±ÑÐ²Ð°Ñ ÐºÐ¾ÑиÑним коли ми маÑмо дÑже довгий ÑиÑловий ÑденÑиÑÑкаÑÐ¾Ñ Ñ Ñ
оÑемо пеÑеÑвоÑиÑи його на ÑоÑÑ ÐºÐ¾ÑоÑÑе, бо Ñ
оÑемо зÑобиÑи URL коÑоÑÑим. ÐÐ»Ñ ÑÑого доÑÑаÑнÑо пÑедÑÑавиÑи його в ÑиÑÑÐµÐ¼Ñ ÑиÑÐ»ÐµÐ½Ð½Ñ Ð· Ð±Ð°Ð·Ð¾Ñ `36`:
+=======
+- **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`:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js run
alert( 123456..toString(36) ); // "2n9c"
@@ -118,7 +136,11 @@ alert( num.toString(2) ); // "11111111"
```warn header="ÐÐ²Ñ ÐºÑапки Ð´Ð»Ñ Ð²Ð¸ÐºÐ»Ð¸ÐºÑ Ð¼ÐµÑодÑ"
ÐвеÑнÑÑÑ ÑвагÑ, Ñо Ð´Ð²Ñ ÐºÑапки в `123456..toString(36)` - Ñе не помилка. ЯкÑо ми Ñ
оÑемо викликаÑи меÑод безпоÑеÑеднÑо на ÑиÑло, напÑиклад `toString` Ñ Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ð¾Ð¼Ñ Ð²Ð¸Ñе пÑикладÑ, ÑÐ¾Ð´Ñ Ð½Ð°Ð¼ поÑÑÑбно поÑÑавиÑи Ð´Ð²Ñ ÐºÑапки `..` пÑÑÐ»Ñ Ð½Ñого.
+<<<<<<< HEAD
Якби ми помÑÑÑили Ð¾Ð´Ð½Ñ ÐºÑапкÑ: `123456.toString(36)`, ÑÐ¾Ð´Ñ Ð²Ð¸Ð½Ð¸ÐºÐ»Ð° б помилка, оÑкÑлÑки ÑинÑакÑÐ¸Ñ JavaScript пеÑедбаÑÐ°Ñ Ð´ÐµÑÑÑÐºÐ¾Ð²Ñ ÑаÑÑÐ¸Ð½Ñ Ð¿ÑÑÐ»Ñ Ð¿ÐµÑÑÐ¾Ñ ÑоÑки. Ð ÑкÑо ми ÑозмÑÑÑимо Ñе Ð¾Ð´Ð½Ñ ÐºÑапкÑ, Ñо JavaScript ÑозпÑзнаÑ, Ñо деÑÑÑкова ÑаÑÑина поÑожнÑ, Ñ Ð´Ð°Ð»Ñ Ð¹Ð´Ðµ меÑод.
+=======
+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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Також можна напиÑаÑи `(123456).toString(36)`.
@@ -137,7 +159,11 @@ alert( num.toString(2) ); // "11111111"
: ÐкÑÑглÑÑ Ð²Ð²ÐµÑÑ
: `3.1` ÑÑÐ°Ñ `4`, Ñа `-1.1` ÑÑÐ°Ñ `-1`.
`Math.round`
+<<<<<<< HEAD
: ÐкÑÑглÑÑ Ð´Ð¾ найближÑого ÑÑлого ÑиÑла: `3.1` ÑÑÐ°Ñ `3`, `3.6` ÑÑÐ°Ñ `4`, `3.5` Ñеж окÑÑглиÑÑ Ð´Ð¾ `4`.
+=======
+: 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`.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
`Math.trunc` (не пÑдÑÑимÑÑÑÑÑÑ Ð² Internet Explorer)
: ÐидалÑÑ Ð²Ñе пÑÑÐ»Ñ Ð´ÐµÑÑÑÐºÐ¾Ð²Ð¾Ñ ÐºÑапки без окÑÑгленнÑ: `3.1` ÑÑÐ°Ñ `3`, `-1.1` ÑÑÐ°Ñ `-1`.
@@ -147,8 +173,10 @@ alert( num.toString(2) ); // "11111111"
| | `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` |
@@ -188,7 +216,11 @@ alert( num.toString(2) ); // "11111111"
alert( num.toFixed(5) ); // "12.34000", додано нÑлÑ, Ñоб зÑобиÑи ÑÑвно 5 ÑиÑÑ
```
+<<<<<<< HEAD
Ðи можемо пеÑеÑвоÑиÑи його на ÑиÑло, викоÑиÑÑовÑÑÑи ÑнаÑний плÑÑ `+num.toFixed(5)` або `Number()`.
+=======
+ We can convert it to a number using the unary plus or a `Number()` call, e.g. write `+num.toFixed(5)`.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
## ÐеÑоÑÐ½Ñ ÑозÑаÑ
Ñнки
@@ -222,7 +254,17 @@ alert( 0.1 + 0.2 ); // 0.30000000000000004
ЧиÑло збеÑÑгаÑÑÑÑÑ Ð² памâÑÑÑ Ñ Ð¹Ð¾Ð³Ð¾ двÑйковÑй ÑоÑмÑ, Ñк поÑлÑдовнÑÑÑÑ Ð±ÑÑÑв - одиниÑÑ Ñ Ð½ÑлÑв. Ðле дÑоби на кÑÑÐ°Ð»Ñ `0.1`, `0.2`, ÑÐºÑ Ð²Ð¸Ð³Ð»ÑдаÑÑÑ Ð¿ÑоÑÑо в деÑÑÑковÑй ÑиÑÑÐµÐ¼Ñ ÑиÑленнÑ, наÑпÑÐ°Ð²Ð´Ñ Ñ Ð½ÐµÑкÑнÑенними дÑобами Ñ ÑвоÑй двÑйковÑй ÑоÑмÑ.
+<<<<<<< HEAD
ÐнÑими Ñловами, Ñо Ñаке `0.1`? Це одиниÑÑ ÑоздÑлена на деÑÑÑÑ `1/10` -- одна деÑÑÑа. У деÑÑÑковÑй ÑиÑÑÐµÐ¼Ñ ÑÐ°ÐºÑ ÑиÑла доÑиÑÑ Ð»ÐµÐ³ÐºÐ¾ пÑедÑÑавиÑи, але ÑкÑо поÑÑвнÑÑи його з однÑÑÑ ÑÑеÑиноÑ: `1/3`, Ñо ми ÑÑикаÑмоÑÑ Ð· неÑкÑнÑенним дÑобом `0.33333(3)`.
+=======
+```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)`.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐÑже, подÑл на `10` гаÑанÑовано пÑаÑÑÑ Ð² деÑÑÑковÑй ÑиÑÑемÑ, але подÑл на `3` - нÑ. Ð ÑÑÑÑ Ð¶ пÑиÑини в ÑиÑÑÐµÐ¼Ñ Ð´Ð²ÑйковиÑ
ÑиÑел подÑл на `2` гаÑанÑовано пÑаÑÑÑ, але `1/10` ÑÑÐ°Ñ Ð½ÐµÑкÑнÑенним двÑйковим дÑобом.
@@ -242,7 +284,11 @@ alert( 0.1.toFixed(20) ); // 0.10000000000000000555
```smart header="Ðе ÑÑлÑки JavaScript"
Ð¦Ñ Ð¶ пÑоблема ÑÑнÑÑ Ñ Ð±Ð°Ð³Ð°ÑÑоÑ
ÑнÑиÑ
моваÑ
пÑогÑамÑваннÑ.
+<<<<<<< HEAD
PHP, Java, C, Perl, Ruby даÑÑÑ Ð°Ð±ÑолÑÑно однаковий ÑезÑлÑÑаÑ, оÑкÑлÑки викоÑиÑÑовÑÑÑÑ Ð¾Ð´Ð¸Ð½ ÑиÑÑовий ÑоÑмаÑ.
+=======
+PHP, Java, C, Perl, and Ruby give exactly the same result, because they are based on the same numeric format.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```
Чи можемо ми виÑÑÑиÑи пÑоблемÑ? ÐвиÑайно, найнадÑйнÑÑий меÑод - окÑÑÐ³Ð»ÐµÐ½Ð½Ñ ÑезÑлÑÑаÑÑ Ð·Ð° Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ Ð¼ÐµÑÐ¾Ð´Ñ [toFixed(n)](https://developer.mozilla.org/uk/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed):
@@ -266,7 +312,11 @@ alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3
alert( (0.28 * 100 + 0.14 * 100) / 100); // 0.4200000000000001
```
+<<<<<<< HEAD
ÐÑже, пÑдÑ
Ñд множеннÑ/дÑÐ»ÐµÐ½Ð½Ñ Ð·Ð¼ÐµÐ½ÑÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ, але не видалÑÑ ÑÑ Ð¿Ð¾Ð²Ð½ÑÑÑÑ.
+=======
+So, the multiply/divide approach reduces the error, but doesn't remove it totally.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐÐ½Ð¾Ð´Ñ Ð¼Ð¾Ð¶Ð½Ð° ÑпÑобÑваÑи ÑникнÑÑи пÑоблем з дÑобами. ЯкÑо ми маÑмо ÑпÑÐ°Ð²Ñ Ð· магазином, Ñо можемо збеÑÑгаÑи ÑÑни в ÑенÑаÑ
замÑÑÑÑ Ð´Ð¾Ð»Ð°ÑÑв. Ðле Ñо ÑобиÑи, ÑкÑо ми заÑÑоÑÑÑмо Ð·Ð½Ð¸Ð¶ÐºÑ Ð² ÑозмÑÑÑ 30%? Ðа пÑакÑиÑÑ Ð¿Ð¾Ð²Ð½ÑÑÑÑ ÑникнÑÑи дÑобÑв вдаÑÑÑÑÑ Ð´Ð¾ÑиÑÑ ÑÑдко. Ð¢Ð¾Ð¼Ñ Ð¿ÑоÑÑо окÑÑглÑйÑе ÑÑ
, Ñоб вÑдÑÑзаÑи "Ñ
воÑÑи", коли Ñе поÑÑÑбно.
@@ -288,7 +338,11 @@ JavaScript не Ð²Ð¸ÐºÐ»Ð¸ÐºÐ°Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÑ Ð² ÑакиÑ
випадкаÑ
.
Це ÑомÑ, Ñо в ÑÑÑÑ
ÑиÑел Ñ Ð¾Ð´Ð¸Ð½ бÑÑ Ð´Ð»Ñ Ð·Ð½Ð°ÐºÐ°. Ð ÑÐ¾Ð¼Ñ Ð·Ð½Ð°Ðº можна вÑÑановиÑи або не вÑÑановиÑи Ð´Ð»Ñ Ð±ÑдÑ-Ñкого ÑиÑла, навÑÑÑ Ð´Ð»Ñ Ð½ÑлÑ.
+<<<<<<< HEAD
У бÑлÑÑоÑÑÑ Ð²Ð¸Ð¿Ð°Ð´ÐºÑв вÑдмÑннÑÑÑÑ Ð½ÐµÐ¿Ð¾Ð¼ÑÑна, оÑкÑлÑки опеÑаÑоÑи пÑдÑ
одÑÑÑ Ð´Ð¾ ниÑ
Ñк до однаковиÑ
.
+=======
+In most cases, the distinction is unnoticeable, because operators are suited to treat them as the same.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```
## ÐеÑевÑÑки: isFinite Ñа isNaN
@@ -337,7 +391,11 @@ alert( isFinite(num) );
````smart header="`Number.isNaN` Ñ `Number.isFinite`"
ÐеÑоди [Number.isNaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) Ñ [Number.isFinite](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite) Ñ Ð±ÑлÑÑ "ÑÑвоÑими" веÑÑÑÑми ÑÑнкÑÑй `isNaN` Ñ `isFinite`. Ðони не пеÑеÑвоÑÑÑÑÑ ÑвÑй аÑгÑÐ¼ÐµÐ½Ñ Ð°Ð²ÑомаÑиÑно на ÑиÑло, а пеÑевÑÑÑÑÑÑ, Ñи належиÑÑ Ð²Ñн до ÑÐ¸Ð¿Ñ `number`.
+<<<<<<< HEAD
- `Number.isNaN(value)` повеÑÑÐ°Ñ `true`, ÑкÑо аÑгÑÐ¼ÐµÐ½Ñ Ð½Ð°Ð»ÐµÐ¶Ð¸ÑÑ Ð´Ð¾ ÑÐ¸Ð¿Ñ `number` Ñ Ð¼Ð°Ñ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ `NaN`. У бÑдÑ-ÑÐºÐ¾Ð¼Ñ ÑнÑÐ¾Ð¼Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÑ Ð²Ñн повеÑÑÐ°Ñ `false`.
+=======
+- `Number.isNaN(value)` returns `true` if the argument belongs to the `number` type and it is `NaN`. In any other case, it returns `false`.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js run
alert( Number.isNaN(NaN) ); // true
@@ -348,7 +406,11 @@ alert( isFinite(num) );
alert( isNaN("str") ); // true, оÑкÑлÑки isNaN пеÑеÑвоÑÑÑ ÑÑдок "str" ââна ÑиÑло Ñа оÑÑимÑÑ NaN Ñк ÑезÑлÑÑÐ°Ñ ÑÑого пеÑеÑвоÑеннÑ
```
+<<<<<<< HEAD
- `Number.isFinite(value)` повеÑÑÐ°Ñ `true`, ÑкÑо аÑгÑÐ¼ÐµÐ½Ñ Ð½Ð°Ð»ÐµÐ¶Ð¸ÑÑ Ð´Ð¾ ÑÐ¸Ð¿Ñ `number` Ñ Ð½Ðµ Ñ `NaN/Infinity/-Infinity`. У бÑдÑ-ÑÐºÐ¾Ð¼Ñ ÑнÑÐ¾Ð¼Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÑ Ð²Ñн повеÑÑÐ°Ñ `false`.
+=======
+- `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`.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js run
alert( Number.isFinite(123) ); // true
@@ -366,8 +428,13 @@ alert( isFinite(num) );
```smart header="ÐоÑÑвнÑÐ½Ð½Ñ Ð· `Object.is`"
ÐÑнÑÑ ÑпеÑÑалÑний вбÑдований меÑод `Object.is`, Ñкий поÑÑвнÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ Ñк `===`, але Ñ Ð±ÑлÑÑ Ð½Ð°Ð´Ñйним Ð´Ð»Ñ Ð´Ð²Ð¾Ñ
винÑÑковиÑ
випадкÑв:
+<<<<<<< HEAD
1. ÐÑаÑÑÑ Ð· `NaN`: `Object.is(NaN, NaN) === true`, Ñ Ñе добÑе.
2. ÐнаÑÐµÐ½Ð½Ñ `0` Ñ` -0` ÑÑзнÑ: `Object.is(0, -0) === false`, ÑеÑ
нÑÑно Ñе пÑавда, оÑкÑлÑки внÑÑÑÑÑнÑо ÑиÑло Ð¼Ð°Ñ Ð±ÑÑ Ð·Ð½Ð°ÐºÑв, Ñкий може бÑÑи ÑÑзним, навÑÑÑ ÑкÑо вÑÑ ÑнÑÑ Ð±ÑÑи -- нÑлÑ.
+=======
+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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
У вÑÑÑ
ÑнÑиÑ
випадкаÑ
`Object.is(a, b)` повеÑне Ñе Ñаме, Ñо й `a === b`.
@@ -385,7 +452,11 @@ alert( +"100px" ); // NaN
ÐинÑÑком Ñ Ð¿ÑобÑли на поÑаÑÐºÑ Ð°Ð±Ð¾ в кÑнÑÑ ÑÑдка, оÑкÑлÑки вони ÑгноÑÑÑÑÑÑÑ.
+<<<<<<< HEAD
Ðле в ÑеалÑÐ½Ð¾Ð¼Ñ Ð¶Ð¸ÑÑÑ Ð¼Ð¸ ÑаÑÑо маÑмо знаÑÐµÐ½Ð½Ñ Ð² конкÑеÑниÑ
одиниÑÑÑ
, напÑиклад, `"100px"` або `"12pt"` в CSS. Також Ñ Ð±Ð°Ð³Ð°ÑÑоÑ
кÑаÑнаÑ
Ñимвол валÑÑи йде пÑÑÐ»Ñ Ð·Ð½Ð°ÑеннÑ, ÑÐ¾Ð¼Ñ Ñ Ð½Ð°Ñ Ñ `"19â¬"` Ñ Ð¼Ð¸ Ñ
оÑемо оÑÑимаÑи ÑиÑло з ÑÑого.
+=======
+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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐÑÑ Ð´Ð»Ñ Ñого пÑизнаÑÐµÐ½Ñ `parseInt` Ñа `parseFloat`.
@@ -479,4 +550,8 @@ JavaScript Ð¼Ð°Ñ Ð²Ð±Ñдований [Math](https://developer.mozilla.org/uk/d
ÐÑлÑÑе маÑемаÑиÑниÑ
ÑÑнкÑÑй:
+<<<<<<< HEAD
- ÐивÑÑÑÑÑ Ð¾Ð±âÑÐºÑ [Math](https://developer.mozilla.org/uk/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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
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 b366456f8..9f686f6b7 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
@@ -11,7 +11,13 @@ importance: 5
ÐапÑиклад:
```js
+<<<<<<< HEAD
truncate("Що Ñ Ñ
оÑÑв би ÑозповÑÑÑи на ÑÑ ÑемÑ:", 20) == "Що Ñ Ñ
оÑÑв би Ñозпоâ¦"
truncate("ÐÑÑм пÑивÑÑ!", 20) == "ÐÑÑм пÑивÑÑ!"
+=======
+truncate("What I'd like to tell on this topic is:", 20) == "What I'd like to teâ¦"
+
+truncate("Hi everyone!", 20) == "Hi everyone!"
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```
diff --git a/1-js/05-data-types/04-array/article.md b/1-js/05-data-types/04-array/article.md
index 0713db8b7..b08aa31b2 100644
--- a/1-js/05-data-types/04-array/article.md
+++ b/1-js/05-data-types/04-array/article.md
@@ -431,7 +431,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
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```
## toString
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 c4d9698f4..b1203af50 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 @@
# ÐеÑоди маÑивÑв
+<<<<<<< HEAD
ÐаÑиви пÑопонÑÑÑÑ Ð±ÐµÐ·Ð»ÑÑ Ð¼ÐµÑодÑв. Щоб бÑло пÑоÑÑÑÑе, в ÑÑÐ¾Ð¼Ñ ÑоздÑÐ»Ñ Ð²Ð¾Ð½Ð¸ ÑозбиÑÑ Ð½Ð° гÑÑпи.
+=======
+Arrays provide a lot of methods. To make things easier, in this chapter, they are split into groups.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
## ÐодаваннÑ/Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ ÐµÐ»ÐµÐ¼ÐµÐ½ÑÑв
@@ -32,11 +36,19 @@ alert( arr.length ); // 3
ÐаÑебÑо, ÐµÐ»ÐµÐ¼ÐµÐ½Ñ Ð±Ñв видалений, але пÑи пеÑевÑÑÑÑ Ð²Ð¸ÑвлÑÑÑÑÑÑ, Ñо маÑив вÑе Ñе Ð¼Ð°Ñ 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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Ð¢Ð¾Ð¼Ñ ÑлÑд заÑÑоÑовÑваÑи ÑпеÑÑалÑÐ½Ñ Ð¼ÐµÑоди.
+<<<<<<< HEAD
ÐеÑод [arr.splice](mdn:js/Array/splice) -- Ñе ÑнÑвеÑÑалÑний «ÑвейÑаÑÑÑкий нÑж» Ð´Ð»Ñ ÑобоÑи з маÑивами. ÐмÑÑ Ð²Ñе: додаваÑи, видалÑÑи Ñ Ð·Ð°Ð¼ÑнÑваÑи елеменÑи.
+=======
+The [arr.splice](mdn:js/Array/splice) method is a Swiss army knife for arrays. It can do everything: insert, remove and replace elements.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Ðого ÑинÑакÑиÑ:
@@ -62,7 +74,11 @@ alert( arr ); // ["I", "JavaScript"]
Ðегко, пÑавда? ÐоÑинаÑÑи з ÑндекÑÑ `1`, вÑн видалив `1` елеменÑ.
+<<<<<<< HEAD
У наÑÑÑÐ¿Ð½Ð¾Ð¼Ñ Ð¿ÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð¼Ð¸ видалÑÑмо 3 елеменÑи Ñа замÑнÑÑмо ÑÑ
двома ÑнÑими:
+=======
+In the next example, we remove 3 elements and replace them with the other two:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js run
let arr = [*!*"I", "study", "JavaScript",*/!* "right", "now"];
@@ -84,7 +100,11 @@ let removed = arr.splice(0, 2);
alert( removed ); // "I", "study" <-- маÑив видалениÑ
елеменÑÑв
```
+<<<<<<< HEAD
ÐеÑод `splice` Ñакож може вÑÑавлÑÑи елеменÑи без бÑдÑ-ÑкиÑ
видаленÑ. ÐÐ»Ñ ÑÑого нам поÑÑÑбно вÑÑановиÑи знаÑÐµÐ½Ð½Ñ `0` Ð´Ð»Ñ `deleteCount`:
+=======
+The `splice` method is also able to insert the elements without any removals. For that, we need to set `deleteCount` to `0`:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js run
let arr = ["I", "study", "JavaScript"];
@@ -114,7 +134,11 @@ alert( arr ); // 1,2,3,4,5
### slice
+<<<<<<< HEAD
ÐеÑод [arr.slice](mdn:js/Array/slice) набагаÑо пÑоÑÑÑÑий, нÑж ÑÑ
ожий на нÑого `arr.splice`.
+=======
+The method [arr.slice](mdn:js/Array/slice) is much simpler than the similar-looking `arr.splice`.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Ðого ÑинÑакÑиÑ:
@@ -124,7 +148,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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐапÑиклад:
@@ -206,7 +234,11 @@ alert( arr.concat(arrayLike) ); // 1,2,something,else
Ðого ÑинÑакÑиÑ:
```js
arr.forEach(function(item, index, array) {
+<<<<<<< HEAD
// ... Ñобимо ÑоÑÑ Ð· item
+=======
+ // ... do something with an item
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
});
```
@@ -239,7 +271,11 @@ arr.forEach(function(item, index, array) {
- `arr.indexOf(item, from)` -- ÑÑÐºÐ°Ñ `item`, поÑинаÑÑи з ÑндекÑÑ `from`, Ñ Ð¿Ð¾Ð²ÐµÑÑÐ°Ñ ÑндекÑ, на ÑÐºÐ¾Ð¼Ñ Ð±Ñв знайдений ÑÑканий елеменÑ, в ÑнÑÐ¾Ð¼Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÑ `-1`.
- `arr.includes(item, from)` -- ÑÑÐºÐ°Ñ `item`, поÑинаÑÑи з ÑндекÑÑ `from`, Ñ Ð¿Ð¾Ð²ÐµÑÑÐ°Ñ `true`, ÑкÑо поÑÑк ÑÑпÑÑний.
+<<<<<<< HEAD
ÐазвиÑай ÑÑ Ð¼ÐµÑоди викоÑиÑÑовÑÑÑÑÑÑ Ð»Ð¸Ñе з одним аÑгÑменÑом: `item` Ð´Ð»Ñ Ð¿Ð¾ÑÑкÑ. Типово поÑÑк вÑдбÑваÑÑÑÑÑ Ð· Ñамого поÑаÑкÑ.
+=======
+Usually, these methods are used with only one argument: the `item` to search. By default, the search is from the beginning.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐапÑиклад:
@@ -255,7 +291,11 @@ alert( arr.includes(1) ); // true
ÐвеÑнÑÑÑ ÑвагÑ, Ñо меÑод `indexOf` викоÑиÑÑовÑÑ ÑÑвоÑе поÑÑвнÑÐ½Ð½Ñ `===`. Таким Ñином, ÑкÑо ми ÑÑкаÑмо `false`, вÑн знаÑ
одиÑÑ Ñаме `false`, але не нÑлÑ.
+<<<<<<< HEAD
ЯкÑо ми Ñ
оÑемо пеÑевÑÑиÑи наÑвнÑÑÑÑ `item` в маÑÑивÑ, Ñ Ð½ÐµÐ¼Ð° поÑÑеби знаÑи його ÑоÑний ÑндекÑ, ÑÐ¾Ð´Ñ ÐºÑаÑе викоÑиÑÑаÑи `arr.includes`.
+=======
+If we want to check if `item` exists in the array and don't need the index, then `arr.includes` is preferred.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐеÑод [arr.lastIndexOf](mdn:js/Array/lastIndexOf) Ñакий Ñамий, Ñк `indexOf`, але ÑÑÐºÐ°Ñ ÑпÑава налÑво.
@@ -274,12 +314,16 @@ const arr = [NaN];
alert( arr.indexOf(NaN) ); // -1 (повинен бÑÑи 0, але === пеÑевÑÑка на ÑÑвнÑÑÑÑ Ð½Ðµ пÑаÑÑÑ Ð· NaN)
alert( arr.includes(NaN) );// true (вÑÑно)
```
-That's because `includes` was added to JavaScript much later and uses the more up to date comparison algorithm internally.
+That's because `includes` was added to JavaScript much later and uses the more up-to-date comparison algorithm internally.
````
### find Ñ findIndex/findLastIndex
+<<<<<<< HEAD
УÑвÑÑÑ, Ñо Ñ Ð½Ð°Ñ Ñ Ð¼Ð°Ñив обʼÑкÑÑв. Як нам знайÑи обʼÑÐºÑ Ð·Ð° Ð¿ÐµÐ²Ð½Ð¾Ñ ÑмовоÑ?
+=======
+Imagine we have an array of objects. How do we find an object with a specific condition?
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ТÑÑ ÑÑане в Ð½Ð°Ð³Ð¾Ð´Ñ Ð¼ÐµÑод [arr.find(fn)](mdn:js/Array/find).
@@ -297,7 +341,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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐапÑиклад, Ñ Ð½Ð°Ñ Ñ Ð¼Ð°Ñив коÑиÑÑÑваÑÑв, кожен з ÑкиÑ
Ð¼Ð°Ñ Ð¿Ð¾Ð»Ñ `id` Ñа `name`. ÐавайÑе знайдемо Ñой де `id == 1`:
@@ -313,11 +361,19 @@ 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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐвеÑнÑÑÑ ÑвагÑ, Ñо в Ð´Ð°Ð½Ð¾Ð¼Ñ Ð¿ÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð¼Ð¸ пеÑедаÑмо `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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐеÑод [arr.findLastIndex](mdn:js/Array/findLastIndex) ÑÑ
ожий на `findIndex`, але ÑÑÐºÐ°Ñ ÑпÑава налÑво, подÑбно до `lastIndexOf`.
@@ -450,11 +506,19 @@ alert(arr); // *!*1, 2, 15*/!*
Ð¢ÐµÐ¿ÐµÑ Ð²Ñе пÑаÑÑÑ Ñк ÑÑеба.
+<<<<<<< HEAD
ÐÑзÑмÑмо паÑÐ·Ñ Ñ Ð¿Ð¾Ð´ÑмаÑмо, Ñо ж вÑдбÑваÑÑÑÑÑ. Ðгаданий ÑанÑÑе маÑив `arr` може бÑÑи маÑивом Ñого завгодно, вÑÑно? ÐÑн може мÑÑÑиÑи ÑиÑла, ÑÑдки, обʼÑкÑи або ÑоÑÑ Ñе. У Ð½Ð°Ñ Ñ Ð½Ð°Ð±ÑÑ ÑкиÑ
оÑÑ ÐµÐ»ÐµÐ¼ÐµÐ½ÑÑв. Щоб впоÑÑдкÑваÑи його, нам поÑÑÑбна ÑÑнкÑÑÑ, Ñка визнаÑÐ°Ñ Ð¿Ð¾ÑÑдок, Ñка знаÑ, Ñк поÑÑвнÑваÑи його елеменÑи. Ðа замовÑÑваннÑм елеменÑи ÑоÑÑÑÑÑÑÑÑ Ñк ÑÑдки.
+=======
+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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐеÑод `arr.sort(fn)` ÑеалÑзÑÑ Ð·Ð°Ð³Ð°Ð»Ñний алгоÑиÑм ÑоÑÑÑваннÑ. Ðам не поÑÑÑбно пÑклÑваÑиÑÑ Ð¿Ñо Ñе, Ñк вÑн пÑаÑÑÑ Ð²ÑеÑÐµÐ´Ð¸Ð½Ñ (в бÑлÑÑоÑÑÑ Ð²Ð¸Ð¿Ð°Ð´ÐºÑв Ñе опÑимÑзоване [Ñвидке ÑоÑÑÑваннÑ](https://en.wikipedia.org/wiki/Quicksort) Ñи [Timsort](https://en.wikipedia.org/wiki/Timsort)). РеалÑзÑÑÑÑÑÑ Ð¿ÑоÑ
Ñд по маÑивÑ, поÑÑвнÑÑÑÑÑÑ Ð¹Ð¾Ð³Ð¾ елеменÑи за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ Ð½Ð°Ð´Ð°Ð½Ð¾Ñ ÑÑнкÑÑÑ Ñ Ð·Ð¼ÑнÑÑÑÑÑÑ ÑÑ
поÑÑдок. ÐÑе, Ñо залиÑаÑÑÑÑÑ Ð½Ð°Ð¼, Ñе надаÑи `fn`, Ñка ÑобиÑÑ Ñе поÑÑвнÑннÑ.
+<<<<<<< HEAD
Ðо ÑеÑÑ, ÑкÑо ми коли-небÑÐ´Ñ Ð·Ð°Ñ
оÑемо дÑзнаÑиÑÑ, ÑÐºÑ ÐµÐ»ÐµÐ¼ÐµÐ½Ñи поÑÑвнÑÑÑÑÑÑ -- нÑÑо не Ð·Ð°Ð²Ð°Ð¶Ð°Ñ Ð½Ð°Ð¼ вивеÑÑи ÑÑ
на екÑан:
+=======
+By the way, if we ever want to know which elements are compared -- nothing prevents us from alerting them:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js run
[1, -2, 15, 2, 0, 8].sort(function(a, b) {
@@ -526,7 +590,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:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js run
let names = 'ÐаÑÑ, ÐеÑÑ, ÐаÑа';
@@ -593,9 +661,15 @@ let value = arr.reduce(function(accumulator, item, index, array) {
- `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`.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐвÑÑиÑÑ Ñкладно?
@@ -664,7 +738,11 @@ arr.reduce((sum, current) => sum + current);
Ð¢Ð¾Ð¼Ñ ÑекомендÑÑÑÑÑÑ Ð·Ð°Ð²Ð¶Ð´Ð¸ вказÑваÑи поÑаÑкове знаÑеннÑ.
+<<<<<<< HEAD
ÐеÑод [arr.reduceRight](mdn:js/Array/reduceRight) пÑаÑÑÑ Ð°Ð½Ð°Ð»Ð¾Ð³ÑÑно, але пÑоÑ
одиÑÑ Ð¿Ð¾ маÑÐ¸Ð²Ñ ÑпÑава налÑво.
+=======
+The method [arr.reduceRight](mdn:js/Array/reduceRight) does the same but goes from right to left.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
## Array.isArray
@@ -689,7 +767,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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐÑÑ Ð¿Ð¾Ð²Ð½Ð¸Ð¹ ÑинÑакÑÐ¸Ñ ÑиÑ
меÑодÑв:
@@ -748,11 +830,19 @@ alert(soldiers[1].age); // 23
- `slice(start, end)` -- ÑÑвоÑÑÑ Ð½Ð¾Ð²Ð¸Ð¹ маÑив, копÑÑÑÑи в нÑого елеменÑи з позиÑÑÑ `start` до `end` (не вклÑÑаÑÑи `end`).
- `concat(...items)` -- повеÑÑÐ°Ñ Ð½Ð¾Ð²Ð¸Ð¹ маÑив: копÑÑÑ Ð²ÑÑ Ñлени поÑоÑного маÑÐ¸Ð²Ñ Ñ Ð´Ð¾Ð´Ð°Ñ Ð´Ð¾ нÑого `items`. ЯкÑо ÑкийÑÑ Ñз `items` Ñ Ð¼Ð°Ñивом, ÑÐ¾Ð´Ñ Ð±ÐµÑÑÑÑÑÑ Ð¹Ð¾Ð³Ð¾ елеменÑи.
+<<<<<<< HEAD
- ÐÐ»Ñ Ð¿Ð¾ÑÑÐºÑ ÑеÑед елеменÑÑв:
- `indexOf/lastIndexOf(item, pos)` -- ÑÑÐºÐ°Ñ `item`, поÑинаÑÑи з позиÑÑÑ `pos`, Ñ Ð¿Ð¾Ð²ÐµÑÑÐ°Ñ Ð¹Ð¾Ð³Ð¾ ÑÐ½Ð´ÐµÐºÑ Ð°Ð±Ð¾ `-1`, ÑкÑо нÑÑого не знайдено.
- `includes(value)` -- повеÑÑÐ°Ñ `true`, ÑкÑо в маÑÐ¸Ð²Ñ Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñ `value`, в ÑнÑÐ¾Ð¼Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÑ `false`.
- `find/filter(func)` -- ÑÑлÑÑÑÑÑ ÐµÐ»ÐµÐ¼ÐµÐ½Ñи ÑеÑез ÑÑнкÑÑÑ Ñ Ð²ÑддаÑÑÑÑÑ Ð¿ÐµÑÑе/вÑÑ Ð·Ð½Ð°ÑеннÑ, пÑи пÑоÑ
Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ ÑкиÑ
ÑÑнкÑÑÑ Ð¿Ð¾Ð²ÐµÑÑÐ°Ñ `true`.
- `findIndex` ÑÑ
ожий на `find`, але повеÑÑÐ°Ñ ÑÐ½Ð´ÐµÐºÑ Ð·Ð°Ð¼ÑÑÑÑ Ð·Ð½Ð°ÑеннÑ.
+=======
+- 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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
- ÐÐ»Ñ Ð¿ÐµÑебоÑÑ ÐµÐ»ÐµÐ¼ÐµÐ½ÑÑв:
- `forEach(func)` -- Ð²Ð¸ÐºÐ»Ð¸ÐºÐ°Ñ `func` Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ елеменÑа. ÐÑÑого не повеÑÑаÑ.
@@ -795,7 +885,11 @@ alert(soldiers[1].age); // 23
Ðовний ÑпиÑок Ñ Ð² [довÑÐ´Ð½Ð¸ÐºÑ MDN](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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Уважно вивÑÑÑÑ ÑпаÑгалкÑ, пÑедÑÑÐ°Ð²Ð»ÐµÐ½Ñ Ð²Ð¸Ñе, а поÑÑм, Ñоб попÑакÑикÑваÑиÑÑ, виÑÑÑиÑе завданнÑ, запÑÐ¾Ð¿Ð¾Ð½Ð¾Ð²Ð°Ð½Ñ Ð² ÑÑÐ¾Ð¼Ñ ÑоздÑлÑ. Так ви оÑÑимаÑÑе необÑ
Ñдний доÑвÑд в пÑавилÑÐ½Ð¾Ð¼Ñ Ð²Ð¸ÐºÐ¾ÑиÑÑÐ°Ð½Ð½Ñ Ð¼ÐµÑодÑв маÑивÑ.
diff --git a/1-js/05-data-types/06-iterable/article.md b/1-js/05-data-types/06-iterable/article.md
index fb0f4ae2f..92256f0e8 100644
--- a/1-js/05-data-types/06-iterable/article.md
+++ b/1-js/05-data-types/06-iterable/article.md
@@ -173,7 +173,11 @@ while (true) {
Ðле ÑÑеÑований обâÑÐºÑ Ð¼Ð¾Ð¶Ðµ не бÑÑи маÑивом. Рнавпаки, пÑевдомаÑив може бÑÑи не ÑÑеÑованим обâÑкÑом.
+<<<<<<< HEAD
ÐапÑиклад, `range` Ñ Ð¿ÑÐ¸ÐºÐ»Ð°Ð´Ñ Ð²Ð¸Ñе Ñ ÑÑеÑованим обâÑкÑом, але не маÑивом, ÑÐ¾Ð¼Ñ Ñо вÑн не Ð¼Ð°Ñ ÑндекÑованиÑ
влаÑÑивоÑÑей Ñа `length`.
+=======
+But an iterable may not be array-like. And vice versa an array-like may not be iterable.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
РоÑÑ Ð¾Ð±âÑкÑ, Ñкий Ñ Ð¿ÑевдомаÑивом, але не ÑÑеÑованим обâÑкÑом:
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 1da611875..7a0d887e8 100644
--- a/1-js/05-data-types/10-destructuring-assignment/article.md
+++ b/1-js/05-data-types/10-destructuring-assignment/article.md
@@ -5,19 +5,32 @@
- ÐбâÑкÑи дозволÑÑÑÑ Ð½Ð°Ð¼ ÑÑвоÑиÑи ÑÐ´Ð¸Ð½Ñ ÑÑÑнÑÑÑÑ, Ñка збеÑÑгаÑиме Ð´Ð°Ð½Ñ Ð·Ð° клÑÑем.
- ÐаÑиви дозволÑÑÑÑ Ð½Ð°Ð¼ зÑбÑаÑи елеменÑи даниÑ
Ñ Ð²Ð¿Ð¾ÑÑдкований ÑпиÑок.
+<<<<<<< HEAD
Ðднак, коли ми пеÑедаÑмо ÑÑ
Ñ ÑÑнкÑÑÑ, нам може знадобиÑиÑÑ Ð½Ðµ вÑе. ФÑнкÑÑÑ Ð¼Ð¾Ð¶ÑÑÑ Ð·Ð½Ð°Ð´Ð¾Ð±Ð¸ÑиÑÑ Ð»Ð¸Ñе Ð¿ÐµÐ²Ð½Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñи або влаÑÑивоÑÑÑ.
+=======
+However, when we pass these to a function, we may not need all of it. The function might only require certain elements or properties.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
*ÐеÑÑÑÑкÑÑÑоване пÑиÑвоÑннÑ* -- Ñе ÑпеÑÑалÑний ÑинÑакÑиÑ, Ñо дозволÑÑ Ð½Ð°Ð¼ "ÑозпаковÑваÑи" маÑиви Ñи обâÑкÑи в кÑÐ¿Ñ Ð·Ð¼ÑнниÑ
, оÑкÑлÑки ÑÐ½Ð¾Ð´Ñ Ñе зÑÑÑнÑÑе.
+<<<<<<< HEAD
ÐеÑÑÑÑкÑÑÑÑÐ²Ð°Ð½Ð½Ñ Ñакож ÑÑдово пÑаÑÑÑ Ð·Ñ Ñкладними ÑÑнкÑÑÑми, ÑÐºÑ Ð¼Ð°ÑÑÑ Ð±Ð°Ð³Ð°Ñо паÑамеÑÑÑв, ÑиповиÑ
знаÑÐµÐ½Ñ ÑоÑо. ÐезабаÑом ми Ñе побаÑимо.
+=======
+Destructuring also works well with complex functions that have a lot of parameters, default values, and so on. Soon we'll see that.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
## ÐеÑÑÑÑкÑÑÑÑÐ²Ð°Ð½Ð½Ñ Ð¼Ð°ÑивÑ
ÐÑÑ Ð¿Ñиклад Ñого, Ñк маÑив деÑÑÑÑкÑÑÑÑÑÑÑÑÑ Ð½Ð° змÑннÑ:
```js
+<<<<<<< HEAD
// Ñ Ð½Ð°Ñ Ñ Ð¼Ð°Ñив з Ñменем Ñа пÑÑзвиÑем
let arr = ["Ðван", "ÐеÑÑенко"]
+=======
+// we have an array with a name and surname
+let arr = ["John", "Smith"]
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
*!*
// деÑÑÑÑкÑÑÑоване пÑиÑвоÑннÑ
@@ -40,10 +53,17 @@ alert(firstName); // Ðван
alert(surname); // ÐеÑÑенко
```
+<<<<<<< HEAD
Як баÑиÑе, ÑинÑакÑÐ¸Ñ Ð¿ÑоÑÑий. ХоÑа Ñ ÐºÑлÑка оÑобливиÑ
деÑалей. ÐавайÑе ÑозглÑнемо бÑлÑÑе пÑикладÑв, Ñоб кÑаÑе Ñе зÑозÑмÑÑи.
````smart header="\"ÐеÑÑÑÑкÑÑÑÑваннÑ\" не ознаÑÐ°Ñ \"ÑÑйнÑваннÑ\"."
Це називаÑÑÑÑÑ "деÑÑÑÑкÑÑÑоване пÑиÑвоÑннÑ", оÑкÑлÑки воно "деÑÑÑÑкÑÑÑÑÑ" ÑлÑÑ
ом копÑÑÐ²Ð°Ð½Ð½Ñ ÐµÐ»ÐµÐ¼ÐµÐ½ÑÑв Ñ Ð·Ð¼ÑннÑ. Ðднак, Ñам маÑив не змÑнÑÑÑÑÑÑ.
+=======
+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. However, the array itself is not modified.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Це пÑоÑÑо коÑоÑÑий ÑпоÑÑб напиÑаÑи:
```js
@@ -65,7 +85,11 @@ let [firstName, , title] = ["ЮлÑй", "ЦезаÑ", "ÐонÑÑл", "РимÑ
alert( title ); // ÐонÑÑл
```
+<<<<<<< HEAD
У Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ð¾Ð¼Ñ Ð²Ð¸Ñе ÐºÐ¾Ð´Ñ Ð´ÑÑгий ÐµÐ»ÐµÐ¼ÐµÐ½Ñ Ð¼Ð°ÑÐ¸Ð²Ñ Ð¿ÑопÑÑкаÑÑÑÑÑ, ÑÑеÑÑй пÑиÑвоÑÑÑÑÑÑ `title`, а ÑеÑÑа елеменÑÑв маÑÐ¸Ð²Ñ Ñакож пÑопÑÑкаÑÑÑÑÑ (оÑкÑлÑки Ð´Ð»Ñ Ð½Ð¸Ñ
Ð½ÐµÐ¼Ð°Ñ Ð·Ð¼ÑнниÑ
).
+=======
+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).
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
````
````smart header="ÐÑаÑÑÑ Ð· бÑдÑ-Ñкими Ñипами даниÑ
, Ñо пеÑебиÑаÑÑÑÑÑ Ñ Ð¿ÑавÑй ÑÑоÑонÑ"
@@ -94,10 +118,17 @@ alert(user.surname); // ÐеÑÑенко
````
+<<<<<<< HEAD
````smart header="Цикл з .entries()"
У попеÑеднÑÐ¾Ð¼Ñ ÑоздÑлÑ, ми баÑили меÑод [Object.entries(obj)](mdn:js/Object/entries).
Ðи можемо викоÑиÑÑовÑваÑи його з деÑÑÑÑкÑÑÑÑваннÑм Ð´Ð»Ñ ÑиклÑÑного пеÑебоÑÑ ÐºÐ»ÑÑÑв-Ñа-знаÑÐµÐ½Ñ Ð¾Ð±âÑкÑа:
+=======
+````smart header="Looping with .entries()"
+In the previous chapter, we saw the [Object.entries(obj)](mdn:js/Object/entries) method.
+
+We can use it with destructuring to loop over the keys-and-values of an object:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js run
let user = {
@@ -105,7 +136,11 @@ let user = {
age: 30
};
+<<<<<<< HEAD
// пеÑебÑаÑи Ñиклом клÑÑÑ-Ñа-знаÑеннÑ
+=======
+// loop over the keys-and-values
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
*!*
for (let [key, value] of Object.entries(user)) {
*/!*
@@ -169,9 +204,15 @@ alert(name2); // ЦезаÑ
let [name1, name2, *!*...rest*/!*] = ["ЮлÑй", "ЦезаÑ", *!*"ÐонÑÑл", "РимÑÑÐºÐ¾Ñ Ð ÐµÑпÑблÑки"*/!*];
*!*
+<<<<<<< HEAD
// rest -- Ñе маÑив елеменÑÑв, поÑинаÑÑи з 3-го
alert(rest[0]); // ÐонÑÑл
alert(rest[1]); // РимÑÑÐºÐ¾Ñ Ð ÐµÑпÑблÑки
+=======
+// rest is an array of items, starting from the 3rd one
+alert(rest[0]); // Consul
+alert(rest[1]); // of the Roman Republic
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
alert(rest.length); // 2
*/!*
```
@@ -187,7 +228,11 @@ let [name1, name2, *!*...titles*/!*] = ["ЮлÑй", "ЦезаÑ", "ÐонÑÑл"
### Ð¢Ð¸Ð¿Ð¾Ð²Ñ Ð·Ð½Ð°ÑеннÑ
+<<<<<<< HEAD
ЯкÑо маÑив коÑоÑÑий за ÑпиÑок змÑнниÑ
злÑва, помилок не бÑде. ÐÑдÑÑÑÐ½Ñ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ Ð²Ð²Ð°Ð¶Ð°ÑÑÑÑÑ Ð½ÐµÐ²Ð¸Ð·Ð½Ð°Ñеними:
+=======
+If the array is shorter than the list of variables on the left, there will be no errors. Absent values are considered undefined:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js run
*!*
@@ -418,7 +463,11 @@ alert( title ); // ÐенÑ
## Ðкладене деÑÑÑÑкÑÑÑÑваннÑ
+<<<<<<< HEAD
ЯкÑо обâÑÐºÑ Ð°Ð±Ð¾ маÑив мÑÑÑÑÑÑ ÑнÑÑ Ð²ÐºÐ»Ð°Ð´ÐµÐ½Ñ Ð¾Ð±âÑкÑи Ñа маÑиви, ми можемо викоÑиÑÑовÑваÑи ÑкладнÑÑÑ Ñаблони з лÑвого Ð±Ð¾ÐºÑ Ð´Ð»Ñ Ð²Ð¸Ð»ÑÑÐµÐ½Ð½Ñ Ð³Ð»Ð¸Ð±ÑиÑ
ÑаÑÑин.
+=======
+If an object or an array contains other nested objects and arrays, we can use more complex left-side patterns to extract deeper portions.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
У Ð½Ð°Ð²ÐµÐ´ÐµÐ½Ð¾Ð¼Ñ Ð½Ð¸Ð¶Ñе ÐºÐ¾Ð´Ñ `options` мÑÑÑиÑÑ ÑнÑий обâÑÐºÑ Ñ Ð²Ð»Ð°ÑÑивоÑÑÑ `size` Ñа маÑив Ñ Ð²Ð»Ð°ÑÑивоÑÑÑ `items`. Шаблон Ñ Ð»ÑвÑй ÑаÑÑÐ¸Ð½Ñ Ð¿ÑиÑвоÑÐ½Ð½Ñ Ð¼Ð°Ñ ÑÑ ÑÐ°Ð¼Ñ ÑÑÑÑкÑÑÑÑ Ð´Ð»Ñ Ð²Ð¸Ð»ÑÑÐµÐ½Ð½Ñ Ð· ниÑ
знаÑенÑ:
@@ -449,7 +498,11 @@ alert(item1); // ТоÑÑ
alert(item2); // ÐонÑик
```
+<<<<<<< HEAD
УÑÑ Ð²Ð»Ð°ÑÑивоÑÑÑ Ð¾Ð±âÑкÑа `options`, окÑÑм `extra`, Ñке вÑдÑÑÑÐ½Ñ Ñ Ð»ÑвÑй ÑаÑÑинÑ, пÑизнаÑаÑÑÑÑÑ Ð²ÑдповÑдним змÑнним:
+=======
+All properties of `options` object except `extra` which is absent in the left part, are assigned to corresponding variables:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533

@@ -459,9 +512,15 @@ alert(item2); // ÐонÑик
## РозÑÐ¼Ð½Ñ Ð¿Ð°ÑамеÑÑи ÑÑнкÑÑÑ
+<<<<<<< HEAD
ÐÑваÑÑÑ Ð²Ð¸Ð¿Ð°Ð´ÐºÐ¸, коли ÑÑнкÑÑÑ Ð¼Ð°Ñ Ð±Ð°Ð³Ð°Ñо паÑамеÑÑÑв, бÑлÑÑÑÑÑÑ Ð· ÑкиÑ
Ñ Ð½ÐµÐ¾Ð±Ð¾Ð²âÑзковими. ÐÑобливо Ñе ÑÑоÑÑÑÑÑÑÑ ÐºÐ¾ÑиÑÑÑваÑÑкиÑ
ÑнÑеÑÑейÑÑв. УÑвÑÑÑ ÑÐ¾Ð±Ñ ÑÑнкÑÑÑ, Ñка ÑÑвоÑÑÑ Ð¼ÐµÐ½Ñ. Ðона може маÑи ÑиÑинÑ, виÑоÑÑ, назвÑ, ÑпиÑок елеменÑÑв ÑоÑо.
ÐижÑе наведено поганий ÑпоÑÑб напиÑаÑи ÑÐ°ÐºÑ ÑÑнкÑÑÑ:
+=======
+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 a function:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js
function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
@@ -469,7 +528,11 @@ function showMenu(title = "Untitled", width = 200, height = 100, items = []) {
}
```
+<<<<<<< HEAD
У ÑеалÑÐ½Ð¾Ð¼Ñ Ð¶Ð¸ÑÑÑ Ð¿Ñоблема полÑÐ³Ð°Ñ Ð² ÑомÑ, Ñк запамâÑÑаÑи поÑÑдок аÑгÑменÑÑв. ÐазвиÑай IDE намагаÑÑÑÑÑ Ð½Ð°Ð¼ допомогÑи, оÑобливо ÑкÑо код добÑе задокÑменÑований, але вÑе ж... ÐнÑа пÑоблема полÑÐ³Ð°Ñ Ð² ÑомÑ, Ñк викликаÑи ÑÑнкÑÑÑ, коли бÑлÑÑÑÑÑÑ Ð¿Ð°ÑамеÑÑÑв Ñипово в поÑÑдкÑ.
+=======
+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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Ðожливо Ñак?
@@ -534,7 +597,11 @@ function({
})
```
+<<<<<<< HEAD
Ð¢Ð¾Ð´Ñ Ð´Ð»Ñ Ð¾Ð±âÑкÑа паÑамеÑÑÑв бÑде змÑнна `varName` Ð´Ð»Ñ Ð²Ð»Ð°ÑÑивоÑÑÑ `incomingProperty` з Ñиповим знаÑеннÑм `defaultValue`.
+=======
+Then, for an object of parameters, there will be a variable `varName` for the property `incomingProperty`, with `defaultValue` by default.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐвеÑнÑÑÑ ÑвагÑ, Ñо Ñаке деÑÑÑÑкÑÑÑÑÐ²Ð°Ð½Ð½Ñ Ð¿ÐµÑедбаÑаÑ, Ñо `showMenu()` Ð¼Ð°Ñ Ð°ÑгÑменÑ. ЯкÑо ми Ñ
оÑемо, Ñоб ÑÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ Ð±Ñли Ñиповими, ми Ð¿Ð¾Ð²Ð¸Ð½Ð½Ñ Ð²ÐºÐ°Ð·Ð°Ñи поÑожнÑй обâÑкÑ:
@@ -561,7 +628,7 @@ showMenu(); // Menu 100 200
- ÐеÑÑÑÑкÑÑÑоване пÑиÑвоÑÐ½Ð½Ñ Ð´Ð¾Ð·Ð²Ð¾Ð»ÑÑ Ð¼Ð¸ÑÑÑво зÑÑÑавиÑи обâÑÐºÑ Ð°Ð±Ð¾ маÑив з багаÑÑма змÑнними.
- Ðовний ÑинÑакÑÐ¸Ñ Ð´Ð»Ñ Ð¾Ð±âÑкÑа:
```js
- let {prop : varName = default, ...rest} = object
+ let {prop : varName = defaultValue, ...rest} = object
```
Це ознаÑаÑ, Ñо влаÑÑивÑÑÑÑ `prop` Ð¼Ð°Ñ Ð²Ñ
одиÑи до змÑÐ½Ð½Ð¾Ñ `varName` Ñ, ÑкÑо ÑÐ°ÐºÐ¾Ñ Ð²Ð»Ð°ÑÑивоÑÑÑ Ð½Ðµ ÑÑнÑÑ, ÑлÑд викоÑиÑÑовÑваÑи `Ñипове` знаÑеннÑ.
@@ -571,9 +638,13 @@ showMenu(); // Menu 100 200
- Ðовний ÑинÑакÑÐ¸Ñ Ð´Ð»Ñ Ð¼Ð°ÑивÑ:
```js
- let [item1 = default, item2, ...rest] = array
+ let [item1 = defaultValue, item2, ...rest] = array
```
+<<<<<<< HEAD
ÐеÑÑий ÐµÐ»ÐµÐ¼ÐµÐ½Ñ Ð¿ÐµÑеÑ
одиÑÑ Ð´Ð¾ `item1`; дÑÑгий пеÑеÑ
одиÑÑ Ð´Ð¾ `item2`, ÑÑÑ ÑнÑÑ ÑÑвоÑÑÑÑÑ Ð¼Ð°Ñив `rest`.
+=======
+ The first item goes to `item1`; the second goes into `item2`, and all the rest makes the array `rest`.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
- Ðожна виÑÑгÑваÑи Ð´Ð°Ð½Ñ Ð· вкладениÑ
маÑивÑв/обâÑкÑÑв, Ð´Ð»Ñ ÑÑого лÑва ÑÑоÑона повинна маÑи ÑÑ Ð¶ ÑÑÑÑкÑÑÑÑ, Ñо й пÑава.
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 ca6c45aa4..d5bc79b60 100644
--- a/1-js/06-advanced-functions/06-function-object/article.md
+++ b/1-js/06-advanced-functions/06-function-object/article.md
@@ -326,7 +326,11 @@ welcome(); // ÐÑивÑÑ, ÐÑÑÑÑ (вкладений виклик вико
Ð¢ÐµÐ¿ÐµÑ Ñе пÑаÑÑÑ, ÑÐ¾Ð¼Ñ Ñо назва `"func"` -- локалÑне Ñ Ð·Ð½Ð°Ñ
одиÑÑÑÑ Ð² ÑеÑÐµÐ´Ð¸Ð½Ñ ÑÑнкÑÑÑ. Ðоно не беÑеÑÑÑÑ Ð·Ð·Ð¾Ð²Ð½Ñ (Ñ Ð½Ðµ доÑÑÑпно звÑдÑи). СпеÑиÑÑкаÑÑÑ Ð³Ð°ÑанÑÑÑ, Ñо воно завжди поÑилаÑÑÑÑÑ Ð½Ð° поÑоÑÐ½Ñ ÑÑнкÑÑÑ.
+<<<<<<< HEAD
ÐовнÑÑнÑй код вÑе Ñе Ð¼Ð°Ñ ÑÐ²Ð¾Ñ Ð·Ð¼ÑÐ½Ð½Ñ `sayHi` або `welcome`. Ð `func` -- Ñе "внÑÑÑÑÑÐ½Ñ ÑмâÑ ÑÑнкÑÑÑ", Ñким ÑÑнкÑÑÑ Ð¼Ð¾Ð¶Ðµ надÑйно викликаÑи Ñебе зÑеÑедини.
+=======
+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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```smart header="Це не пÑаÑÑÑ Ð· Function Declaration"
ФÑнкÑÑоналÑнÑÑÑÑ Ð· "внÑÑÑÑÑнÑÐ¾Ñ Ð½Ð°Ð·Ð²Ð¾Ñ", Ñо опиÑана виÑе, доÑÑÑпна лиÑе Ð´Ð»Ñ Function Expression, а не Ð´Ð»Ñ Function Declaration. ÐÐ»Ñ Function Declaration Ð½ÐµÐ¼Ð°Ñ ÑинÑакÑиÑÑ Ð´Ð»Ñ Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ "внÑÑÑÑÑнÑоÑ" назви.
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 4d36256ee..ecc5c063d 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,9 @@
+<<<<<<< HEAD
Ðомилка Ð²Ð¸Ð½Ð¸ÐºÐ°Ñ ÑÐ¾Ð¼Ñ Ñо `askPassword` оÑÑимÑÑ ÑÑнкÑÑÑ `loginOk/loginFail` без обâÑкÑÑ.
+=======
+The error occurs because `askPassword` gets functions `loginOk/loginFail` without the object.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Ðоли `askPassword` Ð²Ð¸ÐºÐ»Ð¸ÐºÐ°Ñ ÑÑ
, ÑÑ
конÑекÑÑ Ð²ÑÑаÑено `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 511294f48..6ef6ec87f 100644
--- a/1-js/06-advanced-functions/10-bind/article.md
+++ b/1-js/06-advanced-functions/10-bind/article.md
@@ -125,7 +125,11 @@ funcUser(); // Ðван
*/!*
```
+<<<<<<< HEAD
ТÑÑ `func.bind(user)` Ñк "пÑивâÑзаний ваÑÑанÑ" ÑÑнкÑÑÑ `func`, з пÑив'Ñзаним `this=user`.
+=======
+Here `func.bind(user)` is a "bound variant" of `func`, with fixed `this=user`.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐÑÑ Ð°ÑгÑменÑи пеÑедаÑÑÑÑÑ Ð¿Ð¾ÑаÑковÑй ÑÑнкÑÑÑ `func` "Ñк Ñ", напÑиклад:
diff --git a/1-js/08-prototypes/04-prototype-methods/article.md b/1-js/08-prototypes/04-prototype-methods/article.md
index af195b0ae..88dab420a 100644
--- a/1-js/08-prototypes/04-prototype-methods/article.md
+++ b/1-js/08-prototypes/04-prototype-methods/article.md
@@ -14,7 +14,11 @@
ХоÑа Ñ Ð´Ð»Ñ ÑÑого Ñ ÑпеÑÑалÑний меÑод:
+<<<<<<< HEAD
- [Object.create(proto[, descriptors])](mdn:js/Object/create) -- ÑÑвоÑÑÑ Ð¿Ð¾ÑожнÑй обâÑÐºÑ Ñз заданим `proto` Ñк `[[Prototype]]` Ñ Ð½ÐµÐ¾Ð±Ð¾Ð²âÑзковими деÑкÑипÑоÑами влаÑÑивоÑÑей.
+=======
+- [Object.create(proto[, descriptors])](mdn:js/Object/create) -- creates an empty object with given `proto` as `[[Prototype]]` and optional property descriptors.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐапÑиклад:
@@ -116,7 +120,11 @@ alert(obj[key]); // [object Object], не "певне знаÑеннÑ"!
ТÑÑ, ÑкÑо коÑиÑÑÑÐ²Ð°Ñ Ð²Ð²Ð¾Ð´Ð¸ÑÑ `__proto__`, пÑизнаÑÐµÐ½Ð½Ñ Ð² ÑÑÐ´ÐºÑ 4 ÑгноÑÑÑÑÑÑÑ!
+<<<<<<< HEAD
Це, безÑмовно, може бÑÑи дивним Ð´Ð»Ñ Ð½ÐµÑозÑобника, але доÑиÑÑ Ð·ÑозÑмÑлим Ð´Ð»Ñ Ð½Ð°Ñ. ÐлаÑÑивÑÑÑÑ `__proto__` Ñ Ð¾ÑобливоÑ: вона Ð¼Ð°Ñ Ð±ÑÑи або обâÑкÑом, або `null`. Ð Ñдок не може ÑÑаÑи пÑоÑоÑипом. ÐÑÑ ÑÐ¾Ð¼Ñ Ð¿ÑизнаÑÐµÐ½Ð½Ñ ÑÑдка `__proto__` ÑгноÑÑÑÑÑÑÑ.
+=======
+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.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐÑоÑе ми не намагалиÑÑ ÑеалÑзÑваÑи ÑÐ°ÐºÑ Ð¿Ð¾Ð²ÐµÐ´ÑнкÑ. Ðи Ñ
оÑÑли збеÑегÑи паÑи клÑÑ/знаÑÐµÐ½Ð½Ñ Ñ Ð¿Ñи ÑÑÐ¾Ð¼Ñ ÐºÐ»ÑÑ Ð· Ð½Ð°Ð·Ð²Ð¾Ñ `"__proto__"` не збеÑÑгÑÑ. Ð¢Ð¾Ð¼Ñ Ñе помилка!
@@ -203,7 +211,14 @@ alert(Object.keys(chineseDictionary)); // hello,bye
- лÑÑеÑалÑний ÑинÑакÑиÑ: `{ __proto__: ... }`, дозволÑÑ Ð²ÐºÐ°Ð·Ð°Ñи кÑлÑка влаÑÑивоÑÑей
- або [Object.create(proto[, descriptors])](mdn:js/Object/create), дозволÑÑ Ð²ÐºÐ°Ð·Ð°Ñи деÑкÑипÑоÑи влаÑÑивоÑÑей.
+<<<<<<< HEAD
`Object.create` забезпеÑÑÑ Ð¿ÑоÑÑий ÑпоÑÑб повеÑÑ
невого копÑÑÐ²Ð°Ð½Ð½Ñ Ð¾Ð±âÑкÑа з ÑÑÑма деÑкÑипÑоÑами:
+=======
+ - literal syntax: `{ __proto__: ... }`, allows to specify multiple properties
+ - or [Object.create(proto[, descriptors])](mdn:js/Object/create), allows to specify property descriptors.
+
+ The `Object.create` provides an easy way to shallow-copy an object with all descriptors:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js
let clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
diff --git a/1-js/09-classes/06-instanceof/article.md b/1-js/09-classes/06-instanceof/article.md
index 725d79251..c123c03e6 100644
--- a/1-js/09-classes/06-instanceof/article.md
+++ b/1-js/09-classes/06-instanceof/article.md
@@ -55,8 +55,13 @@ alert( arr instanceof Object ); // true
ÐапÑиклад:
```js run
+<<<<<<< HEAD
// задамо пеÑевÑÑÐºÑ instanceof Ñаким Ñином,
// Ñо бÑдÑ-Ñо Ñз влаÑÑивÑÑÑÑ canEat - Ñе ÑваÑина
+=======
+ // set up instanceof check that assumes that
+ // anything with canEat property is an animal
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
class Animal {
static [Symbol.hasInstance](obj) {
if (obj.canEat) return true;
@@ -68,7 +73,11 @@ alert( arr instanceof Object ); // true
alert(obj instanceof Animal); // true: Animal[Symbol.hasInstance](obj) бÑло викликано
```
+<<<<<<< HEAD
2. ÐÑлÑÑÑÑÑÑ ÐºÐ»Ð°ÑÑв не маÑÑÑ `Symbol.hasInstance`. У ÑÑÐ¾Ð¼Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÑ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑÑÑÑÑÑ ÑÑандаÑÑна логÑка: `obj instanceOf Class` пеÑевÑÑÑÑ Ñи `Class.prototype` доÑÑвнÑÑ Ð¾Ð´Ð½Ð¾Ð¼Ñ Ð· пÑоÑоÑипÑв Ñ Ð»Ð°Ð½ÑÑÐ¶ÐºÑ Ð¿ÑоÑоÑипÑв `obj`.
+=======
+2. Most classes do not have `Symbol.hasInstance`. In that case, the standard logic is used: `obj instanceof Class` checks whether `Class.prototype` is equal to one of the prototypes in the `obj` prototype chain.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐнÑими Ñловами, пÑоÑоÑипи поÑÑвнÑÑÑÑÑÑ Ð¾Ð´Ð¸Ð½ за одним:
```js
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 1e5ba12b2..4f524b4aa 100644
--- a/1-js/10-error-handling/1-try-catch/article.md
+++ b/1-js/10-error-handling/1-try-catch/article.md
@@ -637,7 +637,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 .
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Ðони пÑаÑÑÑÑÑ Ð½Ð°ÑÑÑпним Ñином:
diff --git a/1-js/11-async/02-promise-basics/article.md b/1-js/11-async/02-promise-basics/article.md
index 9c28fb3be..e6d0f52f9 100644
--- a/1-js/11-async/02-promise-basics/article.md
+++ b/1-js/11-async/02-promise-basics/article.md
@@ -56,7 +56,7 @@ settled - ÑÑÑалений, завеÑÑений, вÑиÑ
омиÑений;
ÐижÑе пÑиклад конÑÑÑÑкÑоÑа пÑомÑÑа Ñ Ð¿ÑоÑÑÐ¾Ñ ÑÑнкÑÑÑ-виконавÑÑ Ð· кодом-"виÑобником", Ñо Ð²Ð¸Ð´Ð°Ñ ÑезÑлÑÑÐ°Ñ Ð· заÑÑÐ¸Ð¼ÐºÐ¾Ñ (ÑеÑез `setTimeout`):
-```js run
+```js
let promise = new Promise(function(resolve, reject) {
// ÑÑнкÑÑÑ-виÑобник викликаÑÑÑÑÑ Ð°Ð²ÑомаÑиÑно, пÑи Ð²Ð¸ÐºÐ»Ð¸ÐºÑ new Promise
@@ -232,7 +232,11 @@ promise.catch(alert); // виведе "Error: Ðоооой!" ÑеÑез 1 Ñек
ÐапÑиклад зÑпинка заванÑÐ°Ð¶ÐµÐ½Ð½Ñ ÑндикаÑоÑÑв, закÑиÑÑÑ Ð½ÐµÐ¿Ð¾ÑÑÑбниÑ
пÑдклÑÑÐµÐ½Ñ ÑоÑо.
+<<<<<<< HEAD
ÐодÑмайÑе пÑо Ñе Ñк пÑо завеÑÑÐµÐ½Ð½Ñ Ð²ÐµÑÑÑки. Ðезалежно вÑд Ñого, бÑла веÑÑÑка Ñ
оÑоÑÐ¾Ñ Ñи поганоÑ, ÑкÑлÑки дÑÑзÑв на нÑй бÑло, ми вÑе одно Ð¿Ð¾Ð²Ð¸Ð½Ð½Ñ Ð¿ÑибÑаÑи по ÑÑ Ð·Ð°Ð²ÐµÑÑеннÑ.
+=======
+Think of it as a party finisher. Irresepective of whether a party was good or bad, how many friends were in it, we still need (or at least should) do a cleanup after it.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Ðод може виглÑдаÑи Ñак:
diff --git a/1-js/11-async/08-async-await/04-promise-all-failure/solution.md b/1-js/11-async/08-async-await/04-promise-all-failure/solution.md
new file mode 100644
index 000000000..9fda8e000
--- /dev/null
+++ b/1-js/11-async/08-async-await/04-promise-all-failure/solution.md
@@ -0,0 +1,113 @@
+
+The root of the problem is that `Promise.all` immediately rejects when one of its promises rejects, but it do nothing to cancel the other promises.
+
+In our case, the second query fails, so `Promise.all` rejects, and the `try...catch` block catches this error.Meanwhile, other promises are *not affected* - they independently continue their execution. In our case, the third query throws an error of its own after a bit of time. And that error is never caught, we can see it in the console.
+
+The problem is especially dangerous in server-side environments, such as Node.js, when an uncaught error may cause the process to crash.
+
+How to fix it?
+
+An ideal solution would be to cancel all unfinished queries when one of them fails. This way we avoid any potential errors.
+
+However, the bad news is that service calls (such as `database.query`) are often implemented by a 3rd-party library which doesn't support cancellation. Then there's no way to cancel a call.
+
+As an alternative, we can write our own wrapper function around `Promise.all` which adds a custom `then/catch` handler to each promise to track them: results are gathered and, if an error occurs, all subsequent promises are ignored.
+
+```js
+function customPromiseAll(promises) {
+ return new Promise((resolve, reject) => {
+ const results = [];
+ let resultsCount = 0;
+ let hasError = false; // we'll set it to true upon first error
+
+ promises.forEach((promise, index) => {
+ promise
+ .then(result => {
+ if (hasError) return; // ignore the promise if already errored
+ results[index] = result;
+ resultsCount++;
+ if (resultsCount === promises.length) {
+ resolve(results); // when all results are ready - successs
+ }
+ })
+ .catch(error => {
+ if (hasError) return; // ignore the promise if already errored
+ hasError = true; // wops, error!
+ reject(error); // fail with rejection
+ });
+ });
+ });
+}
+```
+
+This approach has an issue of its own - it's often undesirable to `disconnect()` when queries are still in the process.
+
+It may be important that all queries complete, especially if some of them make important updates.
+
+So we should wait until all promises are settled before going further with the execution and eventually disconnecting.
+
+Here's another implementation. It behaves similar to `Promise.all` - also resolves with the first error, but waits until all promises are settled.
+
+```js
+function customPromiseAllWait(promises) {
+ return new Promise((resolve, reject) => {
+ const results = new Array(promises.length);
+ let settledCount = 0;
+ let firstError = null;
+
+ promises.forEach((promise, index) => {
+ Promise.resolve(promise)
+ .then(result => {
+ results[index] = result;
+ })
+ .catch(error => {
+ if (firstError === null) {
+ firstError = error;
+ }
+ })
+ .finally(() => {
+ settledCount++;
+ if (settledCount === promises.length) {
+ if (firstError !== null) {
+ reject(firstError);
+ } else {
+ resolve(results);
+ }
+ }
+ });
+ });
+ });
+}
+```
+
+Now `await customPromiseAllWait(...)` will stall the execution until all queries are processed.
+
+This is a more reliable approach, as it guarantees a predictable execution flow.
+
+Lastly, if we'd like to process all errors, we can use either use `Promise.allSettled` or write a wrapper around it to gathers all errors in a single [AggregateError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError) object and rejects with it.
+
+```js
+// wait for all promises to settle
+// return results if no errors
+// throw AggregateError with all errors if any
+function allOrAggregateError(promises) {
+ return Promise.allSettled(promises).then(results => {
+ const errors = [];
+ const values = [];
+
+ results.forEach((res, i) => {
+ if (res.status === 'fulfilled') {
+ values[i] = res.value;
+ } else {
+ errors.push(res.reason);
+ }
+ });
+
+ if (errors.length > 0) {
+ throw new AggregateError(errors, 'One or more promises failed');
+ }
+
+ return values;
+ });
+}
+```
diff --git a/1-js/11-async/08-async-await/04-promise-all-failure/task.md b/1-js/11-async/08-async-await/04-promise-all-failure/task.md
new file mode 100644
index 000000000..74571c43e
--- /dev/null
+++ b/1-js/11-async/08-async-await/04-promise-all-failure/task.md
@@ -0,0 +1,79 @@
+
+# Dangerous Promise.all
+
+`Promise.all` is a great way to parallelize multiple operations. It's especially useful when we need to make parallel requests to multiple services.
+
+However, there's a hidden danger. We'll see an example in this task and explore how to avoid it.
+
+Let's say we have a connection to a remote service, such as a database.
+
+There're two functions: `connect()` and `disconnect()`.
+
+When connected, we can send requests using `database.query(...)` - an async function which usually returns the result but also may throw an error.
+
+Here's a simple implementation:
+
+```js
+let database;
+
+function connect() {
+ database = {
+ async query(isOk) {
+ if (!isOk) throw new Error('Query failed');
+ }
+ };
+}
+
+function disconnect() {
+ database = null;
+}
+
+// intended usage:
+// connect()
+// ...
+// database.query(true) to emulate a successful call
+// database.query(false) to emulate a failed call
+// ...
+// disconnect()
+```
+
+Now here's the problem.
+
+We wrote the code to connect and send 3 queries in parallel (all of them take different time, e.g. 100, 200 and 300ms), then disconnect:
+
+```js
+// Helper function to call async function `fn` after `ms` milliseconds
+function delay(fn, ms) {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => fn().then(resolve, reject), ms);
+ });
+}
+
+async function run() {
+ connect();
+
+ try {
+ await Promise.all([
+ // these 3 parallel jobs take different time: 100, 200 and 300 ms
+ // we use the `delay` helper to achieve this effect
+*!*
+ delay(() => database.query(true), 100),
+ delay(() => database.query(false), 200),
+ delay(() => database.query(false), 300)
+*/!*
+ ]);
+ } catch(error) {
+ console.log('Error handled (or was it?)');
+ }
+
+ disconnect();
+}
+
+run();
+```
+
+Two of these queries happen to be unsuccessful, but we're smart enough to wrap the `Promise.all` call into a `try..catch` block.
+
+However, this doesn't help! This script actually leads to an uncaught error in console!
+
+Why? How to avoid it?
\ No newline at end of file
diff --git a/1-js/13-modules/02-import-export/article.md b/1-js/13-modules/02-import-export/article.md
index 51383753a..7b7b87f54 100644
--- a/1-js/13-modules/02-import-export/article.md
+++ b/1-js/13-modules/02-import-export/article.md
@@ -96,10 +96,17 @@ say.sayBye('Ðван');
1. Явний ÑпиÑок Ñого, Ñо поÑÑÑбно ÑмпоÑÑÑваÑи Ð´Ð°Ñ ÐºÐ¾ÑоÑÑÑ Ñмена: `sayHi()` замÑÑÑÑ `say.sayHi()`.
2. Явний ÑпиÑок Ñого, Ñо поÑÑÑбно ÑмпоÑÑÑваÑи Ð´Ð°Ñ ÐºÑаÑе ÑозÑмÑÐ½Ð½Ñ ÑÑÑÑкÑÑÑи кодÑ: Ñо викоÑиÑÑано Ñа в ÑÐºÐ¾Ð¼Ñ Ð¼ÑÑÑÑ. Також дозволÑÑ Ð¿ÑдÑÑимÑваÑи Ñа ÑеÑакÑоÑиÑи код легÑе.
+<<<<<<< HEAD
```smart header="Ðе бÑйÑеÑÑ ÑмпоÑÑÑваÑи занадÑо багаÑо"
СÑÑаÑÐ½Ñ ÑнÑÑÑÑменÑи збÑÑки, ÑÐ°ÐºÑ Ñк [webpack](https://webpack.js.org/) Ñа ÑнÑÑ, обâÑднÑÑÑÑ Ð¼Ð¾Ð´ÑÐ»Ñ Ñазом Ñ Ð¾Ð¿ÑимÑзÑÑÑÑ ÑÑ
Ð´Ð»Ñ Ð¿ÑиÑкоÑÐµÐ½Ð½Ñ Ð·Ð°Ð²Ð°Ð½ÑаженнÑ. Ðони Ñакож видалÑÑÑÑ ÑмпоÑÑи, Ñо не викоÑиÑÑовÑÑÑÑÑÑ.
ÐапÑиклад, ÑкÑо ви зÑобиÑе `import * as library` з велиÑÐµÐ·Ð½Ð¾Ñ Ð±ÑблÑоÑеки кодÑ, а поÑÑм викоÑиÑÑаÑÑе лиÑе кÑлÑка меÑодÑв, ÑÐ¾Ð´Ñ Ð½ÐµÐ²Ð¸ÐºÐ¾ÑиÑÑÐ°Ð½Ñ Ð¼ÐµÑоди [не бÑдÑÑÑ Ð²ÐºÐ»ÑÑенÑ](https://github.com/webpack/webpack/tree/main/examples/harmony-unused#examplejs) Ñ Ð¾Ð¿ÑимÑзований бандл.
+=======
+```smart header="Don't be afraid to import too much"
+Modern build tools, such as [webpack](https://webpack.js.org/) and others, bundle modules together and optimize them to speedup loading. They also remove unused imports.
+
+For instance, if you `import * as library` from a huge code library, and then use only few methods, then unused ones [will not be included](https://github.com/webpack/webpack/tree/main/examples/harmony-unused#examplejs) into the optimized bundle.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```
## ÐмпоÑÑ "as"
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/article.md b/1-js/99-js-misc/07-weakref-finalizationregistry/article.md
index 79265e86f..7d12ccce4 100644
--- a/1-js/99-js-misc/07-weakref-finalizationregistry/article.md
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/article.md
@@ -1,4 +1,5 @@
+<<<<<<< HEAD
# WeakRef Ñа FinalizationRegistry
```warn header="\"ÐÑиÑ
ованÑ\" можливоÑÑÑ Ð¼Ð¾Ð²Ð¸"
@@ -31,10 +32,45 @@ user = null;
let user = { name: "John" };
// ÑкопÑÑвали ÑилÑне поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° об'ÑÐºÑ Ñ Ð·Ð¼ÑÐ½Ð½Ñ admin
+=======
+# WeakRef and FinalizationRegistry
+
+```warn header="\"Hidden\" features of the language"
+This article covers a very narrowly focused topic, that most developers extremely rarely encounter in practice (and may not even be aware of its existence).
+
+We recommend skipping this chapter if you have just started learning JavaScript.
+```
+
+Recalling the basic concept of the *reachability principle* from the chapter,
+we can note that the JavaScript engine is guaranteed to keep values in memory that are accessible or in use.
+
+For example:
+
+
+```js
+// the user variable holds a strong reference to the object
+let user = { name: "John" };
+
+// let's overwrite the value of the user variable
+user = null;
+
+// the reference is lost and the object will be deleted from memory
+
+```
+
+Or a similar, but slightly more complicated code with two strong references:
+
+```js
+// the user variable holds a strong reference to the object
+let user = { name: "John" };
+
+// copied the strong reference to the object into the admin variable
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
*!*
let admin = user;
*/!*
+<<<<<<< HEAD
// пеÑезапиÑемо знаÑÐµÐ½Ð½Ñ Ð·Ð¼ÑÐ½Ð½Ð¾Ñ user
user = null;
@@ -58,11 +94,37 @@ let user = { name: "John" };
```
**Слабке поÑиланнÑ** - Ñе поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° об'ÑÐºÑ Ð°Ð±Ð¾ знаÑеннÑ, Ñке *не* запобÑÐ³Ð°Ñ ÑÑ
Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð·Ð±Ð¸ÑаÑем ÑмÑÑÑÑ.
Ðб'ÑÐºÑ Ð°Ð±Ð¾ знаÑÐµÐ½Ð½Ñ Ð¼Ð¾Ð¶ÑÑÑ Ð±ÑÑи Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ñ Ð·Ð±Ð¸ÑаÑем ÑмÑÑÑÑ Ñ Ð²Ð¸Ð¿Ð°Ð´ÐºÑ, ÑкÑо на ниÑ
ÑÑнÑÑÑÑ ÑÑлÑки ÑÐ»Ð°Ð±ÐºÑ Ð¿Ð¾ÑиланнÑ.
+=======
+// let's overwrite the value of the user variable
+user = null;
+
+// the object is still reachable through the admin variable
+```
+The object `{ name: "John" }` would only be deleted from memory if there were no strong references to it (if we also overwrote the value of the `admin` variable).
+
+In JavaScript, there is a concept called `WeakRef`, which behaves slightly differently in this case.
+
+
+````smart header="Terms: \"Strong reference\", \"Weak reference\""
+**Strong reference** - is a reference to an object or value, that prevents them from being deleted by the garbage collector. Thereby, keeping the object or value in memory, to which it points.
+
+This means, that the object or value remains in memory and is not collected by the garbage collector as long, as there are active strong references to it.
+
+In JavaScript, ordinary references to objects are strong references. For example:
+
+```js
+// the user variable holds a strong reference to this object
+let user = { name: "John" };
+```
+**Weak reference** - is a reference to an object or value, that does *not* prevent them from being deleted by the garbage collector.
+An object or value can be deleted by the garbage collector if, the only remaining references to them are weak references.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
````
## WeakRef
+<<<<<<< HEAD
````warn header="ÐаÑÑеÑеженнÑ"
ÐеÑÑ Ð½Ñж ми пеÑейдемо до вивÑеннÑ, ваÑÑо зазнаÑиÑи, Ñо пÑавилÑне заÑÑоÑÑÐ²Ð°Ð½Ð½Ñ ÑÑÑÑкÑÑÑ Ð· ÑÑÑÑ ÑÑаÑÑÑ, Ð²Ð¸Ð¼Ð°Ð³Ð°Ñ Ð´Ñже ÑеÑелÑного обмÑÑковÑваннÑ, Ñ ÑкÑо Ñе можливо, ÑÑ
нÑого викоÑиÑÑÐ°Ð½Ð½Ñ ÐºÑаÑе ÑникаÑи.
````
@@ -82,12 +144,34 @@ let user = { name: "John" };
let user = { name: "John" };
// Ñ Ð·Ð¼ÑннÑй admin знаÑ
одиÑÑÑÑ Ñлабке поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° об'ÑкÑ
+=======
+````warn header="Note of caution"
+Before we dive into it, it is worth noting that the correct use of the structures discussed in this article requires very careful thought, and they are best avoided if possible.
+````
+
+`WeakRef` - is an object, that contains a weak reference to another object, called `target` or `referent`.
+
+The peculiarity of `WeakRef` is that it does not prevent the garbage collector from deleting its referent-object. In other words, a `WeakRef` object does not keep the `referent` object alive.
+
+Now let's take the `user` variable as the "referent" and create a weak reference from it to the `admin` variable.
+To create a weak reference, you need to use the `WeakRef` constructor, passing in the target object (the object you want a weak reference to).
+
+In our case â this is the `user` variable:
+
+
+```js
+// the user variable holds a strong reference to the object
+let user = { name: "John" };
+
+// the admin variable holds a weak reference to the object
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
*!*
let admin = new WeakRef(user);
*/!*
```
+<<<<<<< HEAD
Ðа ÑÑ
ÐµÐ¼Ñ Ð½Ð¸Ð¶Ñе зобÑажено два Ñипи поÑиланÑ: ÑилÑне поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð· викоÑиÑÑаннÑм змÑÐ½Ð½Ð¾Ñ `user` Ñ Ñлабке поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð· викоÑиÑÑаннÑм змÑÐ½Ð½Ð¾Ñ `admin`:

@@ -109,12 +193,36 @@ user = null;
Ðа ÑÑÐ¾Ð¼Ñ ÐµÑапÑ, Ñоб оÑÑимаÑи об'ÑÐºÑ Ð· екземплÑÑÑ `WeakRef`, ми викоÑиÑÑаÑмо його `deref()` меÑод.
ÐеÑод `deref()` повеÑÑÐ°Ñ Ð¾Ð±'ÑкÑ-ÑеÑеÑенÑ, на Ñкий поÑилаÑÑÑÑÑ `WeakRef`, ÑкÑо об'ÑÐºÑ Ð²Ñе Ñе пеÑебÑÐ²Ð°Ñ Ð² пам'ÑÑÑ. ЯкÑо об'ÑÐºÑ Ð±Ñло видалено збиÑаÑем ÑмÑÑÑÑ, - меÑод `deref()` повеÑне `undefined`:
+=======
+The diagram below depicts two types of references: a strong reference using the `user` variable and a weak reference using the `admin` variable:
+
+
+
+Then, at some point, we stop using the `user` variable - it gets overwritten, goes out of scope, etc., while keeping the `WeakRef` instance in the `admin` variable:
+
+```js
+// let's overwrite the value of the user variable
+user = null;
+```
+
+A weak reference to an object is not enough to keep it "alive". When the only remaining references to a referent-object are weak references, the garbage collector is free to destroy this object and use its memory for something else.
+
+However, until the object is actually destroyed, the weak reference may return it, even if there are no more strong references to this object.
+That is, our object becomes a kind of "[Schrödinger's cat](https://en.wikipedia.org/wiki/Schr%C3%B6dinger%27s_cat)" â we cannot know for sure whether it's "alive" or "dead":
+
+
+
+At this point, to get the object from the `WeakRef` instance, we will use its `deref()` method.
+
+The `deref()` method returns the referent-object that the `WeakRef` points to, if the object is still in memory. If the object has been deleted by the garbage collector, then the `deref()` method will return `undefined`:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js
let ref = admin.deref();
if (ref) {
+<<<<<<< HEAD
// об'ÑÐºÑ ÑÑе Ñе доÑÑÑпний: можемо здÑйÑниÑи бÑдÑ-ÑÐºÑ Ð¼Ð°Ð½ÑпÑлÑÑÑÑ Ð· ним
} else {
// об'ÑÐºÑ Ð±Ñло видалено збиÑаÑем ÑмÑÑÑÑ
@@ -262,11 +370,161 @@ const getCachedImg = weakRefCache(fetchImg);
```js
function cleanupCallback(heldValue) {
// код колбека оÑиÑеннÑ
+=======
+ // the object is still accessible: we can perform any manipulations with it
+} else {
+ // the object has been collected by the garbage collector
+}
+```
+
+## WeakRef use cases
+
+`WeakRef` is typically used to create caches or [associative arrays](https://en.wikipedia.org/wiki/Associative_array) that store resource-intensive objects.
+This allows one to avoid preventing these objects from being collected by the garbage collector solely based on their presence in the cache or associative array.
+
+One of the primary examples - is a situation when we have numerous binary image objects (for instance, represented as `ArrayBuffer` or `Blob`), and we want to associate a name or path with each image.
+Existing data structures are not quite suitable for these purposes:
+
+- Using `Map` to create associations between names and images, or vice versa, will keep the image objects in memory since they are present in the `Map` as keys or values.
+- `WeakMap` is ineligible for this goal either: because the objects represented as `WeakMap` keys use weak references, and are not protected from deletion by the garbage collector.
+
+But, in this situation, we need a data structure that would use weak references in its values.
+
+For this purpose, we can use a `Map` collection, whose values are `WeakRef` instances referring to the large objects we need.
+Consequently, we will not keep these large and unnecessary objects in memory longer than they should be.
+
+Otherwise, this is a way to get the image object from the cache if it is still reachable.
+If it has been garbage collected, we will re-generate or re-download it again.
+
+This way, less memory is used in some situations.
+
+## Example â1: using WeakRef for caching
+
+Below is a code snippet that demonstrates the technique of using `WeakRef`.
+
+In short, we use a `Map` with string keys and `WeakRef` objects as their values.
+If the `WeakRef` object has not been collected by the garbage collector, we get it from the cache.
+Otherwise, we re-download it again and put it in the cache for further possible reuse:
+
+```js
+function fetchImg() {
+ // abstract function for downloading images...
+}
+
+function weakRefCache(fetchImg) { // (1)
+ const imgCache = new Map(); // (2)
+
+ return (imgName) => { // (3)
+ const cachedImg = imgCache.get(imgName); // (4)
+
+ if (cachedImg?.deref()) { // (5)
+ return cachedImg?.deref();
+ }
+
+ const newImg = fetchImg(imgName); // (6)
+ imgCache.set(imgName, new WeakRef(newImg)); // (7)
+
+ return newImg;
+ };
+}
+
+const getCachedImg = weakRefCache(fetchImg);
+```
+
+Let's delve into the details of what happened here:
+1. `weakRefCache` - is a higher-order function that takes another function, `fetchImg`, as an argument. In this example, we can neglect a detailed description of the `fetchImg` function, since it can be any logic for downloading images.
+2. `imgCache` - is a cache of images, that stores cached results of the `fetchImg` function, in the form of string keys (image name) and `WeakRef` objects as their values.
+3. Return an anonymous function that takes the image name as an argument. This argument will be used as a key for the cached image.
+4. Trying to get the cached result from the cache, using the provided key (image name).
+5. If the cache contains a value for the specified key, and the `WeakRef` object has not been deleted by the garbage collector, return the cached result.
+6. If there is no entry in the cache with the requested key, or `deref()` method returns `undefined` (meaning that the `WeakRef` object has been garbage collected), the `fetchImg` function downloads the image again.
+7. Put the downloaded image into the cache as a `WeakRef` object.
+
+Now we have a `Map` collection, where the keys - are image names as strings, and values - are `WeakRef` objects containing the images themselves.
+
+This technique helps to avoid allocating a large amount of memory for resource-intensive objects, that nobody uses anymore.
+It also saves memory and time in case of reusing cached objects.
+
+Here is a visual representation of what this code looks like:
+
+
+
+But, this implementation has its drawbacks: over time, `Map` will be filled with strings as keys, that point to a `WeakRef`, whose referent-object has already been garbage collected:
+
+
+
+One way to handle this problem - is to periodically scavenge the cache and clear out "dead" entries.
+Another way - is to use finalizers, which we will explore next.
+
+
+## Example â2: Using WeakRef to track DOM objects
+
+Another use case for `WeakRef` - is tracking DOM objects.
+
+Let's imagine a scenario where some third-party code or library interacts with elements on our page as long as they exist in the DOM.
+For example, it could be an external utility for monitoring and notifying about the system's state (commonly so-called "logger" â a program that sends informational messages called "logs").
+
+Interactive example:
+
+[codetabs height=420 src="weakref-dom"]
+
+When the "Start sending messages" button is clicked, in the so-called "logs display window" (an element with the `.window__body` class), messages (logs) start to appear.
+
+But, as soon as this element is deleted from the DOM, the logger should stop sending messages.
+To reproduce the removal of this element, just click the "Close" button in the top right corner.
+
+In order not to complicate our work, and not to notify third-party code every time our DOM-element is available, and when it is not, it will be enough to create a weak reference to it using `WeakRef`.
+
+Once the element is removed from the DOM, the logger will notice it and stop sending messages.
+
+Now let's take a closer look at the source code (*tab `index.js`*):
+
+1. Get the DOM-element of the "Start sending messages" button.
+2. Get the DOM-element of the "Close" button.
+3. Get the DOM-element of the logs display window using the `new WeakRef()` constructor. This way, the `windowElementRef` variable holds a weak reference to the DOM-element.
+4. Add an event listener on the "Start sending messages" button, responsible for starting the logger when clicked.
+5. Add an event listener on the "Close" button, responsible for closing the logs display window when clicked.
+6. Use `setInterval` to start displaying a new message every second.
+7. If the DOM-element of the logs display window is still accessible and kept in memory, create and send a new message.
+8. If the `deref()` method returns `undefined`, it means that the DOM-element has been deleted from memory. In this case, the logger stops displaying messages and clears the timer.
+9. `alert`, which will be called, after the DOM-element of the logs display window is deleted from memory (i.e. after clicking the "Close" button). **Note, that deletion from memory may not happen immediately, as it depends only on the internal mechanisms of the garbage collector.**
+
+ We cannot control this process directly from the code. However, despite this, we still have the option to force garbage collection from the browser.
+
+ In Google Chrome, for example, to do this, you need to open the developer tools (`key:Ctrl` + `key:Shift` + `key:J` on Windows/Linux or `key:Option` + `key:â` + `key:J` on macOS), go to the "Performance" tab, and click on the bin icon button â "Collect garbage":
+
+ 
+
+
+ This functionality is supported in most modern browsers. After the actions are taken, the alert will trigger immediately.
+
+## FinalizationRegistry
+
+Now it is time to talk about finalizers. Before we move on, let's clarify the terminology:
+
+**Cleanup callback (finalizer)** - is a function that is executed, when an object, registered in the `FinalizationRegistry`, is deleted from memory by the garbage collector.
+
+Its purpose - is to provide the ability to perform additional operations, related to the object, after it has been finally deleted from memory.
+
+**Registry** (or `FinalizationRegistry`) - is a special object in JavaScript that manages the registration and unregistration of objects and their cleanup callbacks.
+
+This mechanism allows registering an object to track and associate a cleanup callback with it.
+Essentially it is a structure that stores information about registered objects and their cleanup callbacks, and then automatically invokes those callbacks when the objects are deleted from memory.
+
+To create an instance of the `FinalizationRegistry`, it needs to call its constructor, which takes a single argument - the cleanup callback (finalizer).
+
+Syntax:
+
+```js
+function cleanupCallback(heldValue) {
+ // cleanup callback code
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
}
const registry = new FinalizationRegistry(cleanupCallback);
```
+<<<<<<< HEAD
ТÑÑ:
- `cleanupCallback` - колбек оÑиÑеннÑ, Ñкий бÑде авÑомаÑиÑно викликаний пÑи Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð·Ð°ÑеÑÑÑÑованого об'ÑкÑа з пам'ÑÑÑ.
@@ -283,21 +541,48 @@ const registry = new FinalizationRegistry(cleanupCallback);
- `unregister(unregisterToken)` - меÑод `unregister` викоÑиÑÑовÑÑÑÑÑÑ Ð´Ð»Ñ ÑкаÑÑÐ²Ð°Ð½Ð½Ñ ÑеÑÑÑÑаÑÑÑ Ð¾Ð±'ÑкÑа в ÑеÑÑÑÑÑ. ÐÑн пÑÐ¸Ð¹Ð¼Ð°Ñ Ð¾Ð´Ð¸Ð½ аÑгÑÐ¼ÐµÐ½Ñ - `unregisterToken` (Ñокен ÑкаÑÑÐ²Ð°Ð½Ð½Ñ ÑеÑÑÑÑаÑÑÑ, Ñкий бÑв оÑÑиманий пÑд ÑÐ°Ñ ÑеÑÑÑÑаÑÑÑ Ð¾Ð±'ÑкÑа).
Ð¢ÐµÐ¿ÐµÑ Ð¿ÐµÑейдемо до пÑоÑÑого пÑикладÑ. СкоÑиÑÑаÑмоÑÑ Ð²Ð¶Ðµ вÑдомим нам об'ÑкÑом `user` Ñ ÑÑвоÑимо екземплÑÑ `FinalizationRegistry`:
+=======
+Here:
+
+- `cleanupCallback` - a cleanup callback that will be automatically called when a registered object is deleted from memory.
+- `heldValue` - the value that is passed as an argument to the cleanup callback. If `heldValue` is an object, the registry keeps a strong reference to it.
+- `registry` - an instance of `FinalizationRegistry`.
+
+`FinalizationRegistry` methods:
+
+- `register(target, heldValue [, unregisterToken])` - used to register objects in the registry.
+
+ `target` - the object being registered for tracking. If the `target` is garbage collected, the cleanup callback will be called with `heldValue` as its argument.
+
+ Optional `unregisterToken` â an unregistration token. It can be passed to unregister an object before the garbage collector deletes it. Typically, the `target` object is used as `unregisterToken`, which is the standard practice.
+- `unregister(unregisterToken)` - the `unregister` method is used to unregister an object from the registry. It takes one argument - `unregisterToken` (the unregister token that was obtained when registering the object).
+
+Now let's move on to a simple example. Let's use the already-known `user` object and create an instance of `FinalizationRegistry`:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js
let user = { name: "John" };
const registry = new FinalizationRegistry((heldValue) => {
+<<<<<<< HEAD
console.log(`${heldValue} бÑв видалений збиÑаÑем ÑмÑÑÑÑ.`);
});
```
ÐоÑÑм заÑеÑÑÑÑÑÑмо об'ÑкÑ, Ð´Ð»Ñ Ñкого поÑÑÑбен колбек оÑиÑеннÑ, викликавÑи меÑод `register`:
+=======
+ console.log(`${heldValue} has been collected by the garbage collector.`);
+});
+```
+
+Then, we will register the object, that requires a cleanup callback by calling the `register` method:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js
registry.register(user, user.name);
```
+<<<<<<< HEAD
РеÑÑÑÑ Ð½Ðµ збеÑÑÐ³Ð°Ñ ÑилÑне поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° об'ÑкÑ, Ñо ÑеÑÑÑÑÑÑÑÑÑÑ, оÑкÑлÑки Ñе б ÑÑпеÑеÑило його пÑизнаÑеннÑ. Якби ÑеÑÑÑÑ Ð·Ð±ÐµÑÑгав ÑилÑне поÑиланнÑ, Ñо об'ÑÐºÑ Ð½Ñколи б не бÑв видалений збиÑаÑем ÑмÑÑÑÑ.
ЯкÑо ж об'ÑÐºÑ Ð²Ð¸Ð´Ð°Ð»ÑÑÑÑÑÑ Ð·Ð±Ð¸ÑаÑем ÑмÑÑÑÑ, Ð½Ð°Ñ ÐºÐ¾Ð»Ð±ÐµÐº оÑиÑÐµÐ½Ð½Ñ Ð¼Ð¾Ð¶Ðµ бÑÑи викликаний в ÑкийÑÑ Ð¼Ð¾Ð¼ÐµÐ½Ñ Ñ Ð¼Ð°Ð¹Ð±ÑÑнÑомÑ, з пеÑеданим Ð¹Ð¾Ð¼Ñ `heldValue`:
@@ -324,6 +609,34 @@ registry.register(user, user.name);
```js
function fetchImg() {
// абÑÑÑакÑна ÑÑнкÑÑÑ Ð´Ð»Ñ Ð·Ð°Ð²Ð°Ð½ÑÐ°Ð¶ÐµÐ½Ð½Ñ Ð·Ð¾Ð±ÑаженÑ...
+=======
+The registry does not keep a strong reference to the object being registered, as this would defeat its purpose. If the registry kept a strong reference, then the object would never be garbage collected.
+
+If the object is deleted by the garbage collector, our cleanup callback may be called at some point in the future, with the `heldValue` passed to it:
+
+```js
+// When the user object is deleted by the garbage collector, the following message will be printed in the console:
+"John has been collected by the garbage collector."
+```
+
+There are also situations where, even in implementations that use a cleanup callback, there is a chance that it will not be called.
+
+For example:
+- When the program fully terminates its operation (for example, when closing a tab in a browser).
+- When the `FinalizationRegistry` instance itself is no longer reachable to JavaScript code.
+ If the object that creates the `FinalizationRegistry` instance goes out of scope or is deleted, the cleanup callbacks registered in that registry might also not be invoked.
+
+## Caching with FinalizationRegistry
+
+Returning to our *weak* cache example, we can notice the following:
+- Even though the values wrapped in the `WeakRef` have been collected by the garbage collector, there is still an issue of "memory leakage" in the form of the remaining keys, whose values have been collected by the garbage collector.
+
+Here is an improved caching example using `FinalizationRegistry`:
+
+```js
+function fetchImg() {
+ // abstract function for downloading images...
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
}
function weakRefCache(fetchImg) {
@@ -356,6 +669,7 @@ function weakRefCache(fetchImg) {
const getCachedImg = weakRefCache(fetchImg);
```
+<<<<<<< HEAD
1. ÐÐ»Ñ ÐºÐµÑÑÐ²Ð°Ð½Ð½Ñ Ð¾ÑиÑеннÑм "меÑÑвиÑ
" запиÑÑв Ñ ÐºÐµÑÑ, коли пов'ÑÐ·Ð°Ð½Ñ Ð· ними об'ÑкÑи `WeakRef` збиÑаÑÑÑÑÑ Ð·Ð±Ð¸ÑаÑем ÑмÑÑÑÑ, ÑÑвоÑÑÑмо ÑеÑÑÑÑ Ð¾ÑиÑÐµÐ½Ð½Ñ `FinalizationRegistry`.
Ðажливим моменÑом ÑÑÑ Ñ Ñе, Ñо в ÐºÐ¾Ð»Ð±ÐµÐºÑ Ð¾ÑиÑÐµÐ½Ð½Ñ Ð¿Ð¾Ð²Ð¸Ð½Ð½Ð¾ пеÑевÑÑÑÑиÑÑ, Ñи бÑв Ð·Ð°Ð¿Ð¸Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð¸Ð¹ збиÑаÑем ÑмÑÑÑÑ Ñ Ñи не бÑв доданий заново, Ñоб не видалиÑи "живий" запиÑ.
@@ -395,10 +709,52 @@ const getCachedImg = weakRefCache(fetchImg);
ÐÑновна ÑÑÑÑ - показаÑи можливий ÑÑенаÑÑй ÑпÑлÑного викоÑиÑÑÐ°Ð½Ð½Ñ `WeakRef` Ñ `FinalizationRegistry` в ÑеалÑÐ½Ð¾Ð¼Ñ Ð¶Ð¸ÑÑÑ.
ÐÑÑ Ñк Ñе виглÑдаÑ:
+=======
+1. To manage the cleanup of "dead" cache entries, when the associated `WeakRef` objects are collected by the garbage collector, we create a `FinalizationRegistry` cleanup registry.
+
+ The important point here is, that in the cleanup callback, it should be checked, if the entry was deleted by the garbage collector and not re-added, in order not to delete a "live" entry.
+2. Once the new value (image) is downloaded and put into the cache, we register it in the finalizer registry to track the `WeakRef` object.
+
+This implementation contains only actual or "live" key/value pairs.
+In this case, each `WeakRef` object is registered in the `FinalizationRegistry`.
+And after the objects are cleaned up by the garbage collector, the cleanup callback will delete all `undefined` values.
+
+Here is a visual representation of the updated code:
+
+
+
+A key aspect of the updated implementation is that finalizers allow parallel processes to be created between the "main" program and cleanup callbacks.
+In the context of JavaScript, the "main" program - is our JavaScript-code, that runs and executes in our application or web page.
+
+Hence, from the moment an object is marked for deletion by the garbage collector, and to the actual execution of the cleanup callback, there may be a certain time gap.
+It is important to understand that during this time gap, the main program can make any changes to the object or even bring it back to memory.
+
+That's why, in the cleanup callback, we must check to see if an entry has been added back to the cache by the main program to avoid deleting "live" entries.
+Similarly, when searching for a key in the cache, there is a chance that the value has been deleted by the garbage collector, but the cleanup callback has not been executed yet.
+
+Such situations require special attention if you are working with `FinalizationRegistry`.
+
+## Using WeakRef and FinalizationRegistry in practice
+
+Moving from theory to practice, imagine a real-life scenario, where a user synchronizes their photos on a mobile device with some cloud service
+(such as [iCloud](https://en.wikipedia.org/wiki/ICloud) or [Google Photos](https://en.wikipedia.org/wiki/Google_Photos)),
+and wants to view them from other devices. In addition to the basic functionality of viewing photos, such services offer a lot of additional features, for example:
+
+- Photo editing and video effects.
+- Creating "memories" and albums.
+- Video montage from a series of photos.
+- ...and much more.
+
+Here, as an example, we will use a fairly primitive implementation of such a service.
+The main point - is to show a possible scenario of using `WeakRef` and `FinalizationRegistry` together in real life.
+
+Here is what it looks like:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533

+<<<<<<< HEAD
ÐÑвоÑÑÑ Ð·Ð½Ð°Ñ
одиÑÑÑÑ Ñ
маÑна бÑблÑоÑека ÑоÑогÑаÑÑй (вони вÑдобÑажаÑÑÑÑÑ Ñ Ð²Ð¸Ð³Ð»ÑÐ´Ñ Ð¼ÑнÑаÑÑÑ).
Ðи можемо вибÑаÑи поÑÑÑÐ±Ð½Ñ Ð½Ð°Ð¼ зобÑÐ°Ð¶ÐµÐ½Ð½Ñ Ñ ÑÑвоÑиÑи колаж, наÑиÑнÑвÑи на ÐºÐ½Ð¾Ð¿ÐºÑ "Create collage" Ñ Ð¿ÑавÑй ÑаÑÑÐ¸Ð½Ñ ÑÑоÑÑнки.
ÐоÑÑм, оÑÑиманий ÑезÑлÑÑÐ°Ñ Ð¼Ð¾Ð¶Ð½Ð° бÑде заванÑажиÑи Ñ Ð²Ð¸Ð³Ð»ÑÐ´Ñ Ð·Ð¾Ð±ÑаженнÑ.
@@ -410,20 +766,41 @@ const getCachedImg = weakRefCache(fetchImg);
ÐижÑе ми баÑимо, Ñо внÑÑÑÑÑнÑй ÑозмÑÑ Ð¼ÑнÑаÑÑÑ ÑÑановиÑÑ 240Ã240 пÑкÑелÑв.
РозмÑÑ Ð±Ñв обÑаний ÑпеÑÑалÑно Ð´Ð»Ñ Ð·Ð±ÑлÑÑÐµÐ½Ð½Ñ ÑвидкоÑÑÑ Ð·Ð°Ð²Ð°Ð½ÑаженнÑ.
ÐÑÑм Ñого, нам не поÑÑÑÐ±Ð½Ñ Ð¿Ð¾Ð²Ð½Ð¾ÑозмÑÑÐ½Ñ ÑоÑогÑаÑÑÑ Ð² ÑÐµÐ¶Ð¸Ð¼Ñ Ð¿Ð¾Ð¿ÐµÑеднÑого пеÑеглÑдÑ.
+=======
+On the left side, there is a cloud library of photos (they are displayed as thumbnails).
+We can select the images we need and create a collage, by clicking the "Create collage" button on the right side of the page.
+Then, the resulting collage can be downloaded as an image.
+
+
+To increase page loading speed, it would be reasonable to download and display photo thumbnails in *compressed* quality.
+But, to create a collage from selected photos, download and use them in *full-size* quality.
+
+Below, we can see, that the intrinsic size of the thumbnails is 240x240 pixels.
+The size was chosen on purpose to increase loading speed.
+Moreover, we do not need full-size photos in preview mode.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533

+<<<<<<< HEAD
ÐÑипÑÑÑимо, Ñо нам поÑÑÑбно ÑÑвоÑиÑи колаж Ñз 4 ÑоÑогÑаÑÑй: ми вибиÑаÑмо ÑÑ
, пÑÑÐ»Ñ Ñого наÑиÑкаÑмо ÐºÐ½Ð¾Ð¿ÐºÑ "Create collage".
Ðа ÑÑÐ¾Ð¼Ñ ÐµÑÐ°Ð¿Ñ Ð²Ð¶Ðµ вÑдома нам ÑÑнкÑÑÑ weakRefCache пеÑевÑÑÑÑ, Ñи Ñ Ð¿Ð¾ÑÑÑбне зобÑÐ°Ð¶ÐµÐ½Ð½Ñ Ð² кеÑÑ.
ЯкÑо нÑ, Ñо заванÑажÑÑ Ð¹Ð¾Ð³Ð¾ з Ñ
маÑи Ñ ÑозмÑÑÑÑ Ð² ÐºÐµÑ Ð´Ð»Ñ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾ÑÑÑ Ð¿Ð¾Ð´Ð°Ð»ÑÑого викоÑиÑÑаннÑ.
Ð Ñак вÑдбÑваÑÑÑÑÑ Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ обÑаного зобÑаженнÑ:
+=======
+Let's assume, that we need to create a collage of 4 photos: we select them, and then click the "Create collage" button.
+At this stage, the already known to us weakRefCache function checks whether the required image is in the cache.
+If not, it downloads it from the cloud and puts it in the cache for further use.
+This happens for each selected image:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533

+<<<<<<< HEAD
ÐвеÑнÑвÑи ÑÐ²Ð°Ð³Ñ Ñо показÑÑ ÐºÐ¾Ð½ÑолÑ, можна побаÑиÑи, ÑÐºÑ Ð· ÑоÑогÑаÑÑй бÑли заванÑÐ°Ð¶ÐµÐ½Ñ Ð· Ñ
маÑи - на Ñе вказÑÑ FETCHED_IMAGE.
ÐÑкÑлÑки Ñе пеÑÑа ÑпÑоба ÑÑвоÑÐµÐ½Ð½Ñ ÐºÐ¾Ð»Ð°Ð¶Ñ, Ñе ознаÑаÑ, Ñо на Ð´Ð°Ð½Ð¾Ð¼Ñ ÐµÑÐ°Ð¿Ñ "Ñлабкий кеÑ" Ñе бÑв поÑожнÑй, а вÑÑ ÑоÑогÑаÑÑÑ Ð±Ñли заванÑÐ°Ð¶ÐµÐ½Ñ Ð· Ñ
маÑи Ñ ÑозмÑÑÐµÐ½Ñ Ð² нÑого.
@@ -431,39 +808,69 @@ const getCachedImg = weakRefCache(fetchImg);
Це ознаÑаÑ, Ñо об'ÑкÑ, Ñкий збеÑÑгаÑÑÑÑÑ Ð² кеÑÑ Ñ Ð½Ð° Ñкий ми поÑилаÑмоÑÑ, викоÑиÑÑовÑÑÑи Ñлабке поÑиланнÑ, видалÑÑÑÑÑÑ Ð·Ð±Ð¸ÑаÑем ÑмÑÑÑÑ.
Ð Ð½Ð°Ñ ÑÑналÑзаÑÐ¾Ñ Ð²Ð¸ÐºÐ¾Ð½ÑÑÑÑÑÑ ÑÑпÑÑно, Ñим Ñамим видалÑÑÑи клÑÑ, за Ñким зобÑÐ°Ð¶ÐµÐ½Ð½Ñ Ð·Ð±ÐµÑÑгалоÑÑ Ð² кеÑÑ.
ÐÑо Ñе Ð½Ð°Ñ Ð¿Ð¾Ð²ÑдомлÑÑ CLEANED_IMAGE:
+=======
+Paying attention to the output in the console, you can see, which of the photos were downloaded from the cloud - this is indicated by FETCHED_IMAGE.
+Since this is the first attempt to create a collage, this means, that at this stage the "weak cache" was still empty, and all the photos were downloaded from the cloud and put in it.
+
+But, along with the process of downloading images, there is also a process of memory cleanup by the garbage collector.
+This means, that the object stored in the cache, which we refer to, using a weak reference, is deleted by the garbage collector.
+And our finalizer executes successfully, thereby deleting the key, by which the image was stored in the cache.
+CLEANED_IMAGE notifies us about it:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533

+<<<<<<< HEAD
ÐÐ°Ð»Ñ Ð¼Ð¸ ÑозÑмÑÑмо, Ñо нам не подобаÑÑÑÑÑ Ð¾ÑÑиманий колаж, Ñ Ð²Ð¸ÑÑÑÑÑмо змÑниÑи одне Ñз зобÑÐ°Ð¶ÐµÐ½Ñ Ñ ÑÑвоÑиÑи новий.
ÐÐ»Ñ ÑÑого доÑÑаÑнÑо пÑибÑаÑи видÑÐ»ÐµÐ½Ð½Ñ Ð· непоÑÑÑбного зобÑаженнÑ, вибÑаÑи ÑнÑе, Ñа Ñе Ñаз наÑиÑнÑÑи на ÐºÐ½Ð¾Ð¿ÐºÑ "Create collage":
+=======
+Next, we realize that we do not like the resulting collage, and decide to change one of the images and create a new one.
+To do this, just deselect the unnecessary image, select another one, and click the "Create collage" button again:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533

+<<<<<<< HEAD
Ðле, ÑÑого ÑÐ°Ð·Ñ Ð½Ðµ вÑÑ Ð·Ð¾Ð±ÑÐ°Ð¶ÐµÐ½Ð½Ñ Ð±Ñли викаÑÐ°Ð½Ñ Ð· меÑежÑ, Ñ Ð¾Ð´Ð½Ðµ з ниÑ
бÑло взÑÑе Ð·Ñ Ñлабкого кеÑÑ: пÑо Ñе нам говоÑиÑÑ Ð¿Ð¾Ð²ÑÐ´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ CACHED_IMAGE.
Це ознаÑаÑ, Ñо на Ð¼Ð¾Ð¼ÐµÐ½Ñ ÑÑвоÑÐµÐ½Ð½Ñ ÐºÐ¾Ð»Ð°Ð¶Ñ Ð·Ð±Ð¸ÑÐ°Ñ ÑмÑÑÑÑ Ñе не видалив наÑе зобÑаженнÑ, Ñ Ð¼Ð¸ ÑмÑливо взÑли його з кеÑа,
Ñим Ñамим ÑкоÑоÑивÑи кÑлÑкÑÑÑÑ Ð¼ÐµÑежевиÑ
запиÑÑв Ñ Ð¿ÑиÑкоÑивÑи загалÑний ÑÐ°Ñ Ð¿ÑоÑеÑÑ ÑÑвоÑÐµÐ½Ð½Ñ ÐºÐ¾Ð»Ð°Ð¶Ñ:
+=======
+But this time not all images were downloaded from the network, and one of them was taken from the weak cache: the CACHED_IMAGE message tells us about it.
+This means that at the time of collage creation, the garbage collector had not yet deleted our image, and we boldly took it from the cache,
+thereby reducing the number of network requests and speeding up the overall time of the collage creation process:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533

+<<<<<<< HEAD
ÐавайÑе Ñе ÑÑоÑ
и "погÑаÑмо", замÑнивÑи одне Ñз зобÑÐ°Ð¶ÐµÐ½Ñ Ñе Ñаз Ñ ÑÑвоÑивÑи новий колаж:
+=======
+Let's "play around" a little more, by replacing one of the images again and creating a new collage:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533

+<<<<<<< HEAD
ЦÑого ÑÐ°Ð·Ñ ÑезÑлÑÑÐ°Ñ Ñе бÑлÑÑ Ð·Ð½Ð°Ñний. Ð 4-ÑоÑ
обÑаниÑ
зобÑаженÑ, 3-Ñи з ниÑ
бÑли взÑÑÑ Ð·Ñ Ñлабкого кеÑÑ, Ñ ÑÑлÑки одне довелоÑÑ Ð·Ð°Ð²Ð°Ð½ÑажиÑи з меÑежÑ.
ÐÐ½Ð¸Ð¶ÐµÐ½Ð½Ñ Ð½Ð°Ð²Ð°Ð½ÑÐ°Ð¶ÐµÐ½Ð½Ñ Ð½Ð° меÑÐµÐ¶Ñ Ñклало близÑко 75%. ÐÑажаÑ, Ñи не Ñак?
+=======
+This time the result is even more impressive. Of the 4 images selected, 3 of them were taken from the weak cache, and only one had to be downloaded from the network.
+The reduction in network load was about 75%. Impressive, isn't it?
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533

+<<<<<<< HEAD
ÐвÑÑно, не ÑлÑд забÑваÑи, Ñо Ñака поведÑнка не Ñ Ð³Ð°ÑанÑованоÑ, Ñ Ð·Ð°Ð»ÐµÐ¶Ð¸ÑÑ Ð²Ñд конкÑеÑÐ½Ð¾Ñ ÑеалÑзаÑÑÑ Ñа ÑобоÑи збиÑаÑа ÑмÑÑÑÑ.
ÐиÑ
одÑÑи з ÑÑого, одÑÐ°Ð·Ñ Ð¶ Ð²Ð¸Ð½Ð¸ÐºÐ°Ñ ÑÑлком логÑÑне запиÑаннÑ: ÑÐ¾Ð¼Ñ Ð± нам не викоÑиÑÑаÑи звиÑайний кеÑ, де ми можемо ÑÐ°Ð¼Ñ ÐºÐµÑÑваÑи його вмÑÑÑом, а не покладаÑиÑÑ Ð½Ð° збиÑÐ°Ñ ÑмÑÑÑÑ?
@@ -481,3 +888,22 @@ const getCachedImg = weakRefCache(fetchImg);
`FinalizationRegistry` - Ñе заÑÑб ÑеÑÑÑÑаÑÑÑ ÐºÐ¾Ð»Ð±ÐµÐºÑв, ÑÐºÑ Ð²Ð¸ÐºÐ¾Ð½ÑÑÑÑÑÑ Ð¿Ñд ÑÐ°Ñ Ð·Ð½Ð¸ÑÐµÐ½Ð½Ñ Ð¾Ð±'ÑкÑÑв, на ÑÐºÑ Ð±ÑлÑÑе Ð½ÐµÐ¼Ð°Ñ ÑилÑниÑ
поÑиланÑ.
Це Ð´Ð°Ñ Ð·Ð¼Ð¾Ð³Ñ Ð·Ð²ÑлÑнÑÑи пов'ÑÐ·Ð°Ð½Ñ Ð· об'ÑкÑом ÑеÑÑÑÑи або виконÑваÑи ÑнÑÑ Ð½ÐµÐ¾Ð±Ñ
ÑÐ´Ð½Ñ Ð¾Ð¿ÐµÑаÑÑÑ Ð¿ÐµÑед видаленнÑм об'ÑкÑа з пам'ÑÑÑ.
+=======
+Of course, it is important to remember, that such behavior is not guaranteed, and depends on the specific implementation and operation of the garbage collector.
+
+Based on this, a completely logical question immediately arises: why do not we use an ordinary cache, where we can manage its entities ourselves, instead of relying on the garbage collector?
+That's right, in the vast majority of cases there is no need to use `WeakRef` and `FinalizationRegistry`.
+
+Here, we simply demonstrated an alternative implementation of similar functionality, using a non-trivial approach with interesting language features.
+Still, we cannot rely on this example, if we need a constant and predictable result.
+
+You can [open this example in the sandbox](sandbox:weakref-finalizationregistry).
+
+## Summary
+
+`WeakRef` - designed to create weak references to objects, allowing them to be deleted from memory by the garbage collector if there are no longer strong references to them.
+This is beneficial for addressing excessive memory usage and optimizing the utilization of system resources in applications.
+
+`FinalizationRegistry` - is a tool for registering callbacks, that are executed when objects that are no longer strongly referenced, are destroyed.
+This allows releasing resources associated with the object or performing other necessary operations before deleting the object from memory.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.html b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.html
index d8c278590..ab383ca9f 100644
--- a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.html
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.html
@@ -1,15 +1,24 @@
+<<<<<<< HEAD
+=======
+
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
+<<<<<<< HEAD
WeakRef DOM ÐогеÑ
+=======
+ WeakRef DOM Logger
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
+<<<<<<< HEAD
ÐÐµÐ¼Ð°Ñ Ð¿Ð¾Ð²ÑдомленÑ.
+=======
+
+
+
+
+ No messages.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.js b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.js
index 3fa1bfda6..05daeee4e 100644
--- a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.js
+++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-dom.view/index.js
@@ -9,10 +9,15 @@ startMessagesBtn.addEventListener('click', () => { // (4)
closeWindowBtn.addEventListener('click', () => document.querySelector(".window__body").remove()); // (5)
+<<<<<<< HEAD
+=======
+
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
const startMessages = (element) => {
const timerId = setInterval(() => { // (6)
if (element.deref()) { // (7)
const payload = document.createElement("p");
+<<<<<<< HEAD
payload.textContent = `ÐовÑдомленнÑ: СÑаÑÑÑ ÑиÑÑеми OK: ${new Date().toLocaleTimeString()}`;
element.deref().append(payload);
} else { // (8)
@@ -21,3 +26,13 @@ const startMessages = (element) => {
}
}, 1000);
};
+=======
+ payload.textContent = `Message: System status OK: ${new Date().toLocaleTimeString()}`;
+ element.deref().append(payload);
+ } else { // (8)
+ alert("The element has been deleted."); // (9)
+ clearInterval(timerId);
+ }
+ }, 1000);
+};
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
diff --git a/2-ui/3-event-details/6-pointer-events/article.md b/2-ui/3-event-details/6-pointer-events/article.md
index 504c5e8cc..21f1199b5 100644
--- a/2-ui/3-event-details/6-pointer-events/article.md
+++ b/2-ui/3-event-details/6-pointer-events/article.md
@@ -126,7 +126,11 @@
Таким Ñином, пÑоблема полÑÐ³Ð°Ñ Ð² ÑомÑ, Ñо бÑаÑÐ·ÐµÑ "викÑадаÑ" взаÑмодÑÑ: `pointercancel` запÑÑкаÑÑÑÑÑ Ð½Ð° поÑаÑÐºÑ Ð¿ÑоÑеÑÑ "пеÑеÑÑгÑваннÑ" Ñ Ð¿Ð¾Ð´ÑÑ `pointermove` бÑлÑÑе не генеÑÑÑÑÑÑÑ.
```online
+<<<<<<< HEAD
ÐÑÑ drag'n'drop демо з ÑеÑÑÑÑаÑÑÑÑ Ð¿Ð¾Ð´Ñй вказÑвника (лиÑе `up/down`, `move` Ñа `cancel`) Ñ `textarea`:
+=======
+Here's the drag'n'drop demo with logging of pointer events (only `up/down`, `move` and `cancel`) in the `textarea`:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
[iframe src="ball" height=240 edit]
```
diff --git a/2-ui/4-forms-controls/1-form-elements/article.md b/2-ui/4-forms-controls/1-form-elements/article.md
index 50e0ceef8..5d0b5502a 100644
--- a/2-ui/4-forms-controls/1-form-elements/article.md
+++ b/2-ui/4-forms-controls/1-form-elements/article.md
@@ -244,7 +244,11 @@ option = new Option(text, value, defaultSelected, selected);
- `defaultSelected` -- ÑкÑо `true`, Ñо до опÑÑÑ Ð±Ñде додано HTML-аÑÑибÑÑ `selected`,
- `selected` -- ÑкÑо `true`, Ñо опÑÑÑ Ð±Ñде обÑаноÑ.
+<<<<<<< HEAD
Ð ÑзниÑÑ Ð¼Ñж `defaultSelected` Ñа `selected` полÑÐ³Ð°Ñ Ð² ÑомÑ, Ñо `defaultSelected` вÑÑановлÑÑ HTML-аÑÑибÑÑ (Ñкий ми можемо оÑÑимаÑи за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ `option.getAttribute('selected')`, ÑÐ¾Ð´Ñ Ñк `selected` визнаÑаÑ, обÑана опÑÑÑ Ñи нÑ.
+=======
+The difference between `defaultSelected` and `selected` is that `defaultSelected` sets the HTML-attribute (that we can get using `option.getAttribute('selected')`), while `selected` sets whether the option is selected or not.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Ðа пÑакÑиÑÑ Ð·Ð°Ð·Ð²Ð¸Ñай ÑлÑд вÑÑановлÑваÑи знаÑÐµÐ½Ð½Ñ _обоÑ
_ паÑамеÑÑÑв на `true` або `false`. (Ðбо пÑоÑÑо не додавайÑе ÑÑ
-- за замовÑÑваннÑм вони маÑÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ `false`.)
diff --git a/2-ui/4-forms-controls/3-events-change-input/article.md b/2-ui/4-forms-controls/3-events-change-input/article.md
index f22cda803..760c10ac6 100644
--- a/2-ui/4-forms-controls/3-events-change-input/article.md
+++ b/2-ui/4-forms-controls/3-events-change-input/article.md
@@ -95,7 +95,11 @@
Ð¢Ð¾Ð¼Ñ Ð±ÑлÑÑÑÑÑÑ Ð±ÑаÑзеÑÑв надаÑÑÑ Ð±ÐµÐ·Ð¿ÐµÑеÑкодний доÑÑÑп Ð´Ð»Ñ ÑиÑаннÑ/запиÑÑ Ð´Ð¾ бÑÑеÑа обмÑÐ½Ñ Ð»Ð¸Ñе в ÑамкаÑ
певниÑ
дÑй коÑиÑÑÑваÑа, ÑакиÑ
Ñк копÑÑваннÑ/вÑÑÐ°Ð²Ð»ÐµÐ½Ð½Ñ ÑоÑо.
+<<<<<<< HEAD
ÐабоÑонено генеÑÑваÑи "коÑиÑÑÑваÑÑкÑ" подÑÑ Ð±ÑÑеÑа обмÑÐ½Ñ Ð· `dispatchEvent` Ñ Ð²ÑÑÑ
бÑаÑзеÑаÑ
, кÑÑм Firefox. РнавÑÑÑ ÑкÑо нам вдаÑÑÑÑÑ Ð²ÑдпÑавиÑи ÑÐ°ÐºÑ Ð¿Ð¾Ð´ÑÑ, Ñ ÑпеÑиÑÑкаÑÑÑ ÑÑÑко зазнаÑено, Ñо ÑÐ°ÐºÑ "ÑинÑеÑиÑнÑ" подÑÑ Ð½Ðµ Ð¿Ð¾Ð²Ð¸Ð½Ð½Ñ Ð½Ð°Ð´Ð°Ð²Ð°Ñи доÑÑÑп до бÑÑеÑа обмÑнÑ.
+=======
+It's forbidden to generate "custom" clipboard events with `dispatchEvent` in all browsers except Firefox. And even if we manage to dispatch such event, the specification clearly states that such "synthetic" events must not provide access to the clipboard.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐавÑÑÑ ÑкÑо Ñ
ÑоÑÑ Ð²Ð¸ÑÑÑиÑÑ Ð·Ð±ÐµÑегÑи `event.clipboardData` в обÑобник подÑй, а поÑÑм оÑÑимаÑи до нÑого доÑÑÑп пÑзнÑÑе -- Ñе не ÑпÑаÑÑÑ.
diff --git a/2-ui/99-ui-misc/02-selection-range/article.md b/2-ui/99-ui-misc/02-selection-range/article.md
index f1fc8d176..eee6361fc 100644
--- a/2-ui/99-ui-misc/02-selection-range/article.md
+++ b/2-ui/99-ui-misc/02-selection-range/article.md
@@ -354,7 +354,11 @@ From
â To
>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Як ми знаÑмо, обâÑкÑи `Range` завжди маÑÑÑ Ð¿Ð¾ÑаÑок(start) пеÑед кÑнÑем(end).
diff --git a/2-ui/99-ui-misc/03-event-loop/2-micro-macro-queue/solution.md b/2-ui/99-ui-misc/03-event-loop/2-micro-macro-queue/solution.md
index 9df988a7d..2e7f668eb 100644
--- a/2-ui/99-ui-misc/03-event-loop/2-micro-macro-queue/solution.md
+++ b/2-ui/99-ui-misc/03-event-loop/2-micro-macro-queue/solution.md
@@ -40,11 +40,20 @@ console.log(7);
ÐÑдведемо пÑдÑÑмки,
+<<<<<<< HEAD
1. ЧиÑла `1` Ñ `7` зâÑвлÑÑÑÑÑÑ Ð²ÑдÑазÑ, ÑÐ¾Ð¼Ñ Ñо пÑоÑÑÑ Ð²Ð¸ÐºÐ»Ð¸ÐºÐ¸ `console.log` не викоÑиÑÑовÑÑÑÑ Ð¶Ð¾Ð´Ð½Ð¸Ñ
ÑеÑг.
2. ÐоÑÑм, пÑÑÐ»Ñ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð½Ñ Ð¾Ñновного поÑÐ¾ÐºÑ ÐºÐ¾Ð´Ñ, запÑÑкаÑÑÑÑÑ ÑеÑга мÑкÑозадаÑ.
- ÐÑн мÑÑÑиÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¸: `console.log(3); setTimeout(...4); console.log(5)`.
- ÐâÑвлÑÑÑÑÑÑ ÑиÑла `3` Ñ `5`, а `setTimeout(() => console.log(4))` Ð´Ð¾Ð´Ð°Ñ Ð²Ð¸ÐºÐ»Ð¸Ðº `console.log(4)` в кÑнеÑÑ ÑеÑги макÑозадаÑ.
- ЧеÑга макÑÐ¾Ð·Ð°Ð´Ð°Ñ ÑÐµÐ¿ÐµÑ Ñака: `console.log(2); console.log(6); console.log(4)`.
3. ÐÑÑÐ»Ñ Ñого Ñк ÑеÑга мÑкÑÐ¾Ð·Ð°Ð´Ð°Ñ ÑÑÐ°Ñ Ð¿Ð¾ÑожнÑоÑ, виконÑÑÑÑÑÑ ÑеÑга макÑозадаÑ. РвÑн виводиÑÑ `2`, `6`, `4`.
+=======
+1. Numbers `1` and `7` show up immediately, because simple `console.log` calls don't use any queues.
+2. Then, after the main code flow is finished, the microtask queue runs.
+ - It has commands: `console.log(3); setTimeout(...4); console.log(5)`.
+ - Numbers `3` and `5` show up, while `setTimeout(() => console.log(4))` adds the `console.log(4)` call to the end of the macrotask queue.
+ - The macrotask queue is now: `console.log(2); console.log(6); console.log(4)`.
+3. After the microtask queue becomes empty, the macrotask queue executes. It outputs `2`, `6`, `4`.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐаÑеÑÑÑ, маÑмо Ñ ÐºÐ¾Ð½ÑолÑ: `1 7 3 5 2 6 4`.
diff --git a/2-ui/99-ui-misc/03-event-loop/article.md b/2-ui/99-ui-misc/03-event-loop/article.md
index 3b0d686a9..0bee0864a 100644
--- a/2-ui/99-ui-misc/03-event-loop/article.md
+++ b/2-ui/99-ui-misc/03-event-loop/article.md
@@ -17,7 +17,11 @@
- виконаÑи ÑÑ
, поÑинаÑÑи з найÑÑаÑÑÑого.
2. ÐÑÑкÑваÑи поки Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð½Ðµ зâÑвиÑÑÑÑ, поÑÑм пеÑейÑи до пÑнкÑÑ 1.
+<<<<<<< HEAD
Це ÑоÑмалÑзаÑÑÑ Ñого, Ñо ми баÑимо, гоÑÑаÑÑи вебÑÑоÑÑнкÑ. Ð ÑÑÑй JavaScript бÑлÑÑÑÑÑÑ ÑаÑÑ Ð½Ðµ ÑобиÑÑ Ð½ÑÑого, вÑн пÑаÑÑÑ Ð»Ð¸Ñе коли ÑпÑаÑÑовÑÑ ÑкÑипÑ, обÑобник подÑй Ñи подÑÑ.
+=======
+That's a formalization of what we see when browsing a page. The JavaScript engine does nothing most of the time, it only runs if a script/handler/event activates.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐÑиклади завданÑ:
@@ -30,6 +34,7 @@
Ðоже ÑÑапиÑиÑÑ Ñак, Ñо Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð¿ÑиÑ
одиÑÑ ÑодÑ, коли ÑÑÑÑй вже зайнÑÑий, ÑÐ¾Ð´Ñ Ñе Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ ÑÑÐ°Ñ Ð² ÑеÑгÑ.
+<<<<<<< HEAD
ЧеÑÐ³Ñ Ð· ÑакиÑ
Ð·Ð°Ð²Ð´Ð°Ð½Ñ Ð½Ð°Ð·Ð¸Ð²Ð°ÑÑÑ "ÑеÑÐ³Ð¾Ñ Ð¼Ð°ÐºÑозавданÑ" ("macrotask queue", ÑеÑмÑн v8):

@@ -37,12 +42,27 @@
ÐапÑиклад, поки ÑÑÑÑй виконÑÑ `script`, коÑиÑÑÑÐ²Ð°Ñ Ð¼Ð¾Ð¶Ðµ поÑÑÑ
аÑи миÑкоÑ, Ñо ÑпÑиÑиниÑÑ Ð¿Ð¾ÑÐ²Ñ Ð¿Ð¾Ð´ÑÑ `mousemove`, Ñа може вийÑи ÑаÑ, запÑогÑамований в `setTimeout` Ñ Ñак далÑ. Ð¦Ñ Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ ÑÑоÑмÑÑÑÑ ÑеÑгÑ, Ñк показано на ÑÑ
ÐµÐ¼Ñ Ð²Ð¸Ñе.
ÐадаÑÑ Ð· ÑеÑги виконÑÑÑÑÑÑ Ð·Ð° пÑавилом "пеÑÑий пÑийÑов â пеÑÑий пÑÑов". Ðоли ÑÑÑÑй бÑаÑзеÑа закÑнÑиÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ `script`, вÑн обÑобиÑÑ Ð¿Ð¾Ð´ÑÑ `mousemove`, поÑÑм Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ Ð¾Ð±Ñобник `setTimeout` ÑоÑо.
+=======
+The tasks form a queue, the so-called "macrotask queue" ([v8](https://v8.dev/) term):
+
+
+
+For instance, while the engine is busy executing a `script`, a user may move their mouse causing `mousemove`, and `setTimeout` may be due and so on, these tasks form a queue, as illustrated in the picture above.
+
+Tasks from the queue are processed on a "first come â first served" basis. When the engine browser is done with the `script`, it handles `mousemove` event, then `setTimeout` handler, and so on.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐÐ¾Ð²Ð¾Ð»Ñ Ð¿ÑоÑÑо наÑазÑ, Ñи не Ñак?
+<<<<<<< HEAD
Ще декÑлÑка деÑалей:
1. РендеÑинг нÑколи не вÑдбÑваÑÑÑÑÑ Ð¿Ð¾ÐºÐ¸ ÑÑÑÑй виконÑÑ Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ. Ðе Ð¼Ð°Ñ Ð·Ð½Ð°ÑÐµÐ½Ð½Ñ Ð½Ð°ÑкÑлÑки довго виконÑÑÑÑÑÑ Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ. ÐмÑни в DOM бÑдÑÑÑ Ð²ÑдмалÑÐ¾Ð²Ð°Ð½Ñ Ð»Ð¸Ñе пÑÑÐ»Ñ Ð·Ð°Ð²ÐµÑÑÐµÐ½Ð½Ñ Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ.
2. ЯкÑо Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð·Ð°Ð¹Ð¼Ð°Ñ Ð½Ð°Ð´Ñо багаÑо ÑаÑÑ, бÑаÑÐ·ÐµÑ Ð½Ðµ зможе виконÑваÑи ÑнÑÑ Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ, напÑиклад, обÑоблÑÑи коÑиÑÑÑваÑÑÐºÑ Ð¿Ð¾Ð´ÑÑ. Тож пÑÑÐ»Ñ Ð½ÐµÐ´Ð¾Ð²Ð³Ð¾Ð³Ð¾ ÑаÑÑ "завиÑаннÑ" зâÑвиÑÑÑÑ Ð¾Ð¿Ð¾Ð²ÑÑÐµÐ½Ð½Ñ "СÑоÑÑнка не вÑдповÑдаÑ" Ñ Ð¿ÑопозиÑÑÑ Ð²Ð±Ð¸Ñи пÑоÑÐµÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ñазом з ÑÑÐ»Ð¾Ñ ÑÑоÑÑнкоÑ. Таке ÑÑаплÑÑÑÑÑÑ ÐºÐ¾Ð»Ð¸ код мÑÑÑиÑÑ Ð±Ð°Ð³Ð°Ñо ÑкладниÑ
обÑаÑ
ÑнкÑв або Ð²Ð¸Ð½Ð¸ÐºÐ°Ñ Ð¿ÑогÑамна помилка, Ñо ÑÑвоÑÑÑ Ð½ÐµÑкÑнÑенний Ñикл.
+=======
+Two more details:
+1. Rendering never happens while the engine executes a task. It doesn't matter if the task takes a long time. Changes to the DOM are painted only after the task is complete.
+2. If a task takes too long, the browser can't do other tasks, such as processing user events. So after some time, it raises an alert like "Page Unresponsive", suggesting killing the task with the whole page. That happens when there are a lot of complex calculations or a programming error leading to an infinite loop.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Що ж, Ñе бÑла ÑеоÑÑÑ. Ð¢ÐµÐ¿ÐµÑ Ð¿Ð¾Ð±Ð°Ñимо Ñк можна викоÑиÑÑаÑи ÑÑ Ð·Ð½Ð°Ð½Ð½Ñ Ð½Ð° пÑакÑиÑÑ.
@@ -54,7 +74,11 @@
Ðоки ÑÑÑÑй зайнÑÑий пÑдÑвÑÑÑваннÑм ÑинÑакÑиÑÑ Ð²Ñн не може виконÑваÑи ÑнÑÑ ÑеÑÑ, повâÑÐ·Ð°Ð½Ñ Ð· DOM, обÑоблÑÑи коÑиÑÑÑваÑÑÐºÑ Ð¿Ð¾Ð´ÑÑ ÑоÑо. Це може ÑпÑиÑиниÑи "завиÑаннÑ" бÑаÑзеÑа, Ñо Ñ Ð½ÐµÐ¿ÑийнÑÑним.
+<<<<<<< HEAD
Ðи можемо ÑникнÑÑи пÑоблем ÑлÑÑ
ом ÑÐ¾Ð·Ð±Ð¸Ð²Ð°Ð½Ð½Ñ Ð²ÐµÐ»Ð¸ÐºÐ¾Ð³Ð¾ Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð½Ð° ÑмаÑоÑки. ÐÑдÑвÑÑиÑи пеÑÑÑ 100 ÑÑдкÑв, поÑÑм поÑÑавиÑи `setTimeout` (з нÑлÑÐ¾Ð²Ð¾Ñ Ð·Ð°ÑÑимкоÑ) Ð´Ð»Ñ Ð½Ð°ÑÑÑпниÑ
100 ÑÑдкÑв Ñ Ñак далÑ.
+=======
+We can avoid problems by splitting the big task into pieces. Highlight the first 100 lines, then schedule `setTimeout` (with zero-delay) for the next 100 lines, and so on.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Щоб пÑодемонÑÑÑÑваÑи Ñакий пÑдÑ
Ñд, замÑÑÑÑ Ð¿ÑдÑвÑÑÑÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ ÑпÑоÑÐµÐ½Ð½Ñ Ð²ÑзÑмемо ÑÑнкÑÑÑ, Ñка ÑаÑ
ÑÑ Ð²Ñд `1` до `1000000000`.
diff --git a/6-data-storage/01-cookie/article.md b/6-data-storage/01-cookie/article.md
index e2f9fef13..4be42f220 100644
--- a/6-data-storage/01-cookie/article.md
+++ b/6-data-storage/01-cookie/article.md
@@ -2,17 +2,31 @@
Файли cookies («кÑки») -- Ñе Ð½ÐµÐ²ÐµÐ»Ð¸ÐºÑ ÑÑдки з даними, ÑÐºÑ Ð·Ð±ÐµÑÑгаÑÑÑÑÑ Ð±ÐµÐ·Ð¿Ð¾ÑеÑеднÑо в бÑаÑзеÑÑ. Ðони Ñ ÑаÑÑÐ¸Ð½Ð¾Ñ HTTP пÑоÑоколÑ, визнаÑеного ÑпеÑиÑÑкаÑÑÑÑ [RFC 6265](https://tools.ietf.org/html/rfc6265).
+<<<<<<< HEAD
Файли cookies зазвиÑай вÑÑановлÑÑÑÑÑÑ Ð²ÐµÐ±ÑеÑвеÑом за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ° HTTP `Set-Cookie`. ÐоÑÑм бÑаÑÐ·ÐµÑ Ð°Ð²ÑомаÑиÑно додаваÑиме ÑÑ
пÑи (майже) ÐºÐ¾Ð¶Ð½Ð¾Ð¼Ñ Ð·Ð°Ð¿Ð¸ÑÑ Ð´Ð¾ вÑдповÑдного Ð´Ð¾Ð¼ÐµÐ½Ñ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑÑÑи заголовок HTTP `Cookie`.
+=======
+Cookies are usually set by a web server using the response `Set-Cookie` HTTP header. Then, the browser automatically adds them to (almost) every request to the same domain using the `Cookie` HTTP header.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Ðдним з найбÑлÑÑ Ð¿Ð¾ÑиÑениÑ
випадкÑв викоÑиÑÑÐ°Ð½Ð½Ñ Ñ Ð°ÑÑенÑиÑÑкаÑÑÑ:
+<<<<<<< HEAD
1. ÐÑи вÑ
Ð¾Ð´Ñ Ð² ÑиÑÑемÑ, ÑеÑÐ²ÐµÑ Ð²Ð¸ÐºÐ¾ÑиÑÑовÑÑ Ð²ÑдповÑÐ´Ñ Ð¾ÑÑÐ¸Ð¼Ð°Ð½Ñ Ð· заголовка HTTP `Set-Cookie`, Ñоб додаÑи в Ñайл cookie ÑнÑкалÑний "ÑденÑиÑÑкаÑÐ¾Ñ ÑеÑÑÑ" .
2. ÐаÑÑÑпного ÑазÑ, коли на Ñой Ñамий домен бÑде вÑдпÑавлено запиÑ, бÑаÑÐ·ÐµÑ Ð½Ð°Ð´ÑÑле Ñайл cookie викоÑиÑÑовÑÑÑи заголовок HTTP `Cookie`.
3. Таким Ñином, ÑеÑÐ²ÐµÑ Ð·Ð½Ð°Ñ, Ñ
Ñо зÑобив запиÑ.
+=======
+1. Upon sign-in, the server uses the `Set-Cookie` HTTP header in the response to set a cookie with a unique "session identifier".
+2. Next time the request is sent to the same domain, the browser sends the cookie over the net using the `Cookie` HTTP header.
+3. So the server knows who made the request.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Також ми маÑмо доÑÑÑп до ÑайлÑв cookies з бÑаÑзеÑа, викоÑиÑÑовÑÑÑи влаÑÑивÑÑÑÑ `document.cookie`.
+<<<<<<< HEAD
У ÑайлаÑ
cookies Ñа ÑÑ
нÑÑ
аÑÑибÑÑаÑ
Ñ Ð±Ð°Ð³Ð°Ñо ÑонкоÑÑв. Ð ÑÑÐ¾Ð¼Ñ ÑоздÑÐ»Ñ Ð¼Ð¸ деÑалÑно ÑÑ
ÑозглÑнемо.
+=======
+There are many tricky things about cookies and their attributes. In this chapter, we'll cover them in detail.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
## ÐÑиÑÑÐ²Ð°Ð½Ð½Ñ Ð· document.cookie
@@ -31,17 +45,29 @@ alert( document.cookie ); // cookie1=value1; cookie2=value2;...
```
+<<<<<<< HEAD
ÐнаÑÐµÐ½Ð½Ñ `document.cookie` ÑкладаÑÑÑÑÑ Ð· Ð¿Ð°Ñ `name=value` ÑоздÑлениÑ
`; `. Ðожна паÑа -- Ñе окÑемий Ñайл cookie.
Щоб знайÑи певний Ñайл cookie поÑÑÑбно ÑоздÑлиÑи знаÑÐµÐ½Ð½Ñ `document.cookie` за Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ `; `, а поÑÑм знайÑи поÑÑÑбний клÑÑ Ð·Ð° його назвоÑ. ÐÐ»Ñ ÑÑого можна викоÑиÑÑовÑваÑи Ñк ÑегÑлÑÑÐ½Ñ Ð²Ð¸Ñази, Ñак Ñ ÑÑнкÑÑÑ Ð´Ð»Ñ ÑобоÑи з маÑивами.
ÐалиÑимо Ñе Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð´Ð»Ñ ÑамоÑÑÑÐ¹Ð½Ð¾Ñ ÑобоÑи ÑиÑаÑа. ÐкÑÑм Ñого, в кÑнÑÑ ÑоздÑÐ»Ñ Ð²Ð¸ знайдеÑе допомÑÐ¶Ð½Ñ ÑÑнкÑÑÑ Ð´Ð»Ñ ÑобоÑи з Ñайлами cookies.
+=======
+The value of `document.cookie` consists of `name=value` pairs, delimited by `;â`. Each one is a separate cookie.
+
+To find a particular cookie, we can split `document.cookie` by `;â`, and then find the right name. We can use either a regular expression or array functions to do that.
+
+We leave it as an exercise for the reader. Also, at the end of the chapter, you'll find helper functions to manipulate cookies.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
## ÐÐ°Ð¿Ð¸Ñ Ð² document.cookie
Ðи можемо запиÑÑваÑи в `document.cookie`. Ðле Ñе не пÑоÑÑо влаÑÑивоÑÑÑ Ð´Ð°Ð½Ð¸Ñ
, Ñе [акÑеÑоÑи (геÑеÑи/ÑеÑеÑи)](info:property-accessors). ÐÑиÑвоÑÐ½Ð½Ñ ÑиÑ
влаÑÑивоÑÑей обÑоблÑÑÑÑÑÑ Ð¾Ñобливим Ñином.
+<<<<<<< HEAD
**ÐÐ°Ð¿Ð¸Ñ Ð² `document.cookie` оновлÑÑ Ð»Ð¸Ñе вказаний Ñайл cookie, Ñа не ÑÑпаÑиме ÑеÑÑÑ.**
+=======
+**A write operation to `document.cookie` updates only the cookie mentioned in it and doesn't touch other cookies.**
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐапÑиклад, Ñей виклик вÑÑановиÑÑ Ñайл cookie з Ñменем `user` Ñа знаÑеннÑм `John`:
@@ -50,12 +76,20 @@ document.cookie = "user=John"; // оновиÑи лиÑе Ñайл cookie пÑд
alert(document.cookie); // показаÑи вÑÑ Ñайли cookies
```
+<<<<<<< HEAD
ЯкÑо ви запÑÑÑиÑе Ñей код, Ñо, ÑвидÑе за вÑе, побаÑиÑе декÑлÑка ÑайлÑв cookies. Це ÑомÑ, Ñо опеÑаÑÑÑ `document.cookie=` оновлÑÑ Ð½Ðµ вÑÑ Ñайли cookies, а лиÑе вказаний Ñайли з Ñменем `user`.
+=======
+If you run it, you will likely see multiple cookies. That's because the `document.cookie=` operation does not overwrite all cookies. It only sets the mentioned cookie `user`.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ТеÑ
нÑÑно, ÑмâÑ Ñа знаÑÐµÐ½Ð½Ñ Ð¼Ð¾Ð¶ÑÑÑ Ð¼ÑÑÑиÑи бÑдÑ-ÑÐºÑ Ñимволи. Щоб збеÑегÑи пÑавилÑне ÑоÑмаÑÑваннÑ, вони Ð¿Ð¾Ð²Ð¸Ð½Ð½Ñ Ð±ÑÑи ÐºÐ¾Ð´Ð¾Ð²Ð°Ð½Ñ Ð·Ð° Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ Ð²Ð±ÑÐ´Ð¾Ð²Ð°Ð½Ð¾Ñ ÑÑнкÑÑÑ `encodeURIComponent`.
```js run
+<<<<<<< HEAD
// ÑпеÑÑалÑÐ½Ñ Ñимволи (пÑобÑли, киÑилиÑÑ), поÑÑебÑÑÑÑ ÐºÐ¾Ð´ÑваннÑ
+=======
+// special characters (spaces) need encoding
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
let name = "my name";
let value = "John Smith";
@@ -66,6 +100,7 @@ alert(document.cookie); // ...; my%20name=John%20Smith
```
+<<<<<<< HEAD
```warn header="ÐбмеженнÑ"
РдекÑлÑка обмеженÑ:
- Ðа Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ `document.cookie`, ви можеÑе вÑÑановиÑи/оновиÑи лиÑе один Ñайл cookie.
@@ -76,6 +111,18 @@ alert(document.cookie); // ...; my%20name=John%20Smith
Файли cookies маÑÑÑ ÑÑд аÑÑибÑÑÑв, деÑÐºÑ Ð· ниÑ
Ð²Ð°Ð¶Ð»Ð¸Ð²Ñ Ñ Ð¿Ð¾Ð²Ð¸Ð½Ð½Ñ Ð±ÑÑи заданÑ.
ÐÑÑибÑÑи пеÑеÑаÑ
овÑÑÑÑÑÑ Ð¿ÑÑÐ»Ñ Ð¿Ð°Ñи `key=value` Ñа ÑоздÑлÑÑÑÑÑÑ `; `, Ñк показано нижÑе:
+=======
+```warn header="Limitations"
+There are a few limitations:
+- You can only set/update a single cookie at a time using `document.cookie`.
+- The `name=value` pair, after `encodeURIComponent`, should not exceed 4KB. So we can't store anything huge in a cookie.
+- The total number of cookies per domain is limited to around 20+, the exact limit depends on the browser.
+```
+
+Cookies have several attributes, many of which are important and should be set.
+
+The attributes are listed after `key=value`, delimited by `;`, like this:
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js run
document.cookie = "user=John; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT"
@@ -93,7 +140,11 @@ document.cookie = "user=John; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT"
Типово, Ñайли cookie доÑÑÑÐ¿Ð½Ñ Ð»Ð¸Ñе на ÑÐ¾Ð¼Ñ Ð´Ð¾Ð¼ÐµÐ½Ñ Ð½Ð° ÑÐºÐ¾Ð¼Ñ Ð±Ñли вÑÑановленÑ.
+<<<<<<< HEAD
ÐвеÑнÑÑÑ ÑвагÑ, Ñо Ñипово Ñайли cookie Ñакож не доÑÑÑÐ¿Ð½Ñ Ñ Ð½Ð° пÑддоменÑ, ÑÐ°ÐºÐ¾Ð¼Ñ Ñк `forum.site.com`.
+=======
+Please note, by default, a cookie is not shared with a subdomain, such as `forum.site.com`.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js
// ÑкÑо задаÑи Ñайл cookie на вебÑайÑÑ site.com ...
@@ -105,7 +156,11 @@ alert(document.cookie); // коÑиÑÑÑваÑа немаÑ
...ÐÑоÑе ÑÑ Ð¿Ð¾Ð²ÐµÐ´ÑÐ½ÐºÑ Ð¼Ð¾Ð¶Ð½Ð° змÑниÑи. ЯкÑо ми Ñ
оÑемо дозволиÑи пÑддоменам на кÑÑÐ°Ð»Ñ `forum.site.com` оÑÑимÑваÑи Ñайли cookie Ð·Ð°Ð´Ð°Ð½Ñ Ð½Ð° `site.com` -- Ñе Ñакож можливо.
+<<<<<<< HEAD
ÐÐ»Ñ ÑÑого, вÑÑановлÑÑÑи Ñайл cookie за адÑеÑÐ¾Ñ `site.com`, ми Ð¿Ð¾Ð²Ð¸Ð½Ð½Ñ Ñвно задаÑи в аÑÑибÑÑÑ `domain` коÑеневий домен: `domain=site.com`. Ð¢Ð¾Ð´Ñ Ð²ÑÑ Ð¿Ñддомени побаÑаÑÑ Ñакий Ñайл cookie.
+=======
+For that to happen, when setting a cookie at `site.com`, we should explicitly set the `domain` attribute to the root domain: `domain=site.com`. Then all subdomains will see such a cookie.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐапÑиклад:
@@ -120,16 +175,25 @@ document.cookie = "user=John; *!*domain=site.com*/!*"
alert(document.cookie); // Ñайл cookie user=John ÑÑнÑÑ
```
+<<<<<<< HEAD
```warn header="ÐаÑÑаÑÑлий ÑинÑакÑиÑ"
ÐÑÑоÑиÑно ÑклалоÑÑ Ñак Ñо, `domain=.site.com`(з кÑÐ°Ð¿ÐºÐ¾Ñ Ð¿ÐµÑед `site.com`) ÑпÑаÑÑÑ Ñак Ñамо, надаÑÑи доÑÑÑп до ÑайлÑв cookie з пÑддоменÑв. Ð¢ÐµÐ¿ÐµÑ ÐºÑапки на поÑаÑÐºÑ Ð´Ð¾Ð¼ÐµÐ½Ð½Ð¸Ñ
Ñмен ÑгноÑÑÑÑÑÑÑ, але деÑÐºÑ Ð±ÑаÑзеÑи можÑÑÑ Ð²ÑдмовиÑиÑÑ Ð²ÑÑановлÑваÑи Ñайл cookie, Ñо мÑÑÑиÑÑ ÑÐ°ÐºÑ ÐºÑапки.
```
ÐÑже, аÑÑибÑÑ `domain` ÑобиÑÑ Ñайли cookie доÑÑÑпними на пÑддоменаÑ
.
+=======
+```warn header="Legacy syntax"
+Historically, `domain=.site.com` (with a dot before `site.com`) used to work the same way, allowing access to the cookie from subdomains. Leading dots in domain names are now ignored, but some browsers may decline to set the cookie containing such dots.
+```
+
+To summarize, the `domain` attribute allows to make a cookie accessible at subdomains.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
## path
- **`path=/mypath`**
+<<<<<<< HEAD
URL-пÑеÑÑÐºÑ Ð°Ð´ÑеÑи повинен бÑÑи абÑолÑÑним. ÐÐ»Ñ Ñого Ñоб Ñайли cookie бÑли доÑÑÑпними Ð·Ñ ÑÑоÑÑнок за ÑÑÑÑ Ð°Ð´ÑеÑоÑ. Типово, Ñе поÑоÑна ÑÑоÑÑнка.
ЯкÑо в ÑÐ°Ð¹Ð»Ñ cookie задано `path=/admin`, Ñо вÑн видимий на ÑÑоÑÑнкаÑ
`/admin` Ñа `/admin/something`, але не на `/home` або `/adminpage`.
@@ -145,6 +209,23 @@ URL-пÑеÑÑÐºÑ Ð°Ð´ÑеÑи повинен бÑÑи абÑолÑÑним. Ð
- **`expires=Tue, 19 Jan 2038 03:14:07 GMT`**
ТеÑмÑн пÑидаÑноÑÑÑ ÑÐ°Ð¹Ð»Ñ cookie визнаÑÐ°Ñ ÑаÑ, коли бÑаÑÐ·ÐµÑ Ð°Ð²ÑомаÑиÑно видалиÑÑ Ð¹Ð¾Ð³Ð¾ (вÑдповÑдно до ÑаÑового поÑÑÑ Ð±ÑаÑзеÑа).
+=======
+The URL path prefix must be absolute. It makes the cookie accessible for pages under that path. By default, it's the current path.
+
+If a cookie is set with `path=/admin`, it's visible on pages `/admin` and `/admin/something`, but not at `/home`, `/home/admin` or `/`.
+
+Usually, we should set `path` to the root: `path=/` to make the cookie accessible from all website pages. If this attribute is not set the default is calculated using [this method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#path_default_value).
+
+## expires, max-age
+
+By default, if a cookie doesn't have one of these attributes, it disappears when the browser/tab is closed. Such cookies are called "session cookies"
+
+To let cookies survive a browser close, we can set either the `expires` or `max-age` attribute. `max-Age` has precedence if both are set.
+
+- **`expires=Tue, 19 Jan 2038 03:14:07 GMT`**
+
+The cookie expiration date defines the time when the browser will automatically delete it (according to the browser's time zone).
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ÐаÑа Ð¼Ð°Ñ Ð±ÑÑи вказана Ñаме в ÑÐ°ÐºÐ¾Ð¼Ñ ÑоÑмаÑÑ, в ÑаÑÐ¾Ð²Ð¾Ð¼Ñ Ð¿Ð¾ÑÑÑ GMT. Щоб оÑÑимаÑи пÑавилÑÐ½Ñ Ð´Ð°ÑÑ, можна ÑкоÑиÑÑаÑиÑÑ `date.toUTCString`. ÐапÑиклад, можемо вÑÑановиÑи, Ñо ÑеÑмÑн пÑидаÑноÑÑÑ ÑÐ°Ð¹Ð»Ñ cookie закÑнÑÑÑÑÑÑÑ ÑеÑез 1 денÑ:
@@ -181,7 +262,11 @@ document.cookie = "user=John; max-age=0";
ТобÑо Ñайли cookie базÑÑÑÑÑÑ Ð½Ð° доменÑ, вони не залежаÑÑ Ð²Ñд пÑоÑоколÑв.
+<<<<<<< HEAD
Ð ÑÐ°Ð·Ñ ÑкÑо Ñей аÑÑибÑÑ Ð·Ð°Ð´Ð°Ð½Ð¾, Ñо Ñайл cookie ÑÑвоÑений на `https://site.com` не бÑде доÑÑÑпний на ÑÐ¾Ð¼Ñ Ð¶ вебÑайÑÑ Ð· HTTP-пÑоÑоколом `http://site.com`. Ð¢Ð¾Ð¼Ñ ÑкÑо Ñайли cookie мÑÑÑÑÑÑ ÐºÐ¾Ð½ÑÑденÑÑÐ¹Ð½Ñ Ð´Ð°Ð½Ñ, ÑÐºÑ Ð² Ð¶Ð¾Ð´Ð½Ð¾Ð¼Ñ ÑÐ°Ð·Ñ Ð½Ðµ маÑÑÑ Ð±ÑÑи вÑдпÑÐ°Ð²Ð»ÐµÐ½Ñ Ð¿Ð¾ незаÑиÑÑÐ¾Ð²Ð°Ð½Ð¾Ð¼Ñ HTTP-пÑоÑоколÑ, ÑÐ¾Ð´Ñ Ð¿Ð°ÑамеÑÑ `secure` Ñе пÑавилÑний вибÑÑ.
+=======
+With this attribute, if a cookie is set by `https://site.com`, then it doesn't appear when the same site is accessed by HTTP, as `http://site.com`. So if a cookie has sensitive content that should never be sent over unencrypted HTTP, the `secure` flag is the right thing.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
```js
// пÑипÑÑÑимо, Ñо заÑаз ми на https://
@@ -191,16 +276,25 @@ document.cookie = "user=John; secure";
## samesite
+<<<<<<< HEAD
Це Ñе один аÑÑибÑÑ Ð±ÐµÐ·Ð¿ÐµÐºÐ¸. ÐÑн ÑÑвоÑений Ñоб заÑ
иÑаÑи вÑд Ñак званиÑ
XSRF-аÑак (мÑжÑайÑова пÑдмÑна запиÑÑ).
+=======
+This is another security attribute `samesite`. It's designed to protect from so-called XSRF (cross-site request forgery) attacks.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
Щоб зÑозÑмÑÑи Ñк вÑн пÑаÑÑÑ Ñа в ÑкиÑ
випадкаÑ
може бÑÑи коÑиÑним, давайÑе деÑалÑнÑÑе ÑозглÑнемо понÑÑÑÑ XSRF-аÑак.
### XSRF-аÑаки
+<<<<<<< HEAD
УÑвÑÑÑ, Ñо ви ÑвÑйÑли в ÑвÑй облÑковий Ð·Ð°Ð¿Ð¸Ñ Ð½Ð° ÑайÑÑ `bank.com`. ТобÑо: Ñ Ð²Ð°Ñ Ñ Ñайли cookie з даними аÑÑенÑиÑÑкаÑÑÑ Ð²Ñд ÑÑого ÑайÑÑ. ÐÐ°Ñ Ð±ÑаÑÐ·ÐµÑ Ð²ÑдпÑавлÑÑ ÑÑ
ÑайÑÑ `bank.com` пÑи ÐºÐ¾Ð¶Ð½Ð¾Ð¼Ñ Ð·Ð°Ð¿Ð¸ÑÑ, Ð´Ð»Ñ Ñого Ñоб Ñой ÑозпÑзнав Ð²Ð°Ñ Ñа виконав вÑÑ ÐºÐ¾Ð½ÑÑденÑÑÐ¹Ð½Ñ ÑÑнанÑÐ¾Ð²Ñ Ð¾Ð¿ÐµÑаÑÑÑ.
+=======
+Imagine, you are logged into the site `bank.com`. That is: you have an authentication cookie from that site. Your browser sends it to `bank.com` with every request so that it recognizes you and performs all sensitive financial operations.
+>>>>>>> 5e893cffce8e2346d4e50926d5148c70af172533
ТепеÑ, пеÑеглÑдаÑÑи вебÑÑоÑÑнки в ÑнÑÐ¾Ð¼Ñ Ð²ÑкнÑ, ви випадково поÑÑапили на ÑÐ°Ð¹Ñ `evil.com`. Цей ÑÐ°Ð¹Ñ Ð¼ÑÑÑиÑÑ ÐºÐ¾Ð´ JavaScript, Ñкий вÑдпÑавлÑÑ ÑоÑÐ¼Ñ `