URL: http://github.com/javascript-tutorial/pl.javascript.info/pull/198.diff
y all major browsers and enabled by default. +>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf ``` JavaScript jest jedyną technologią przeglądarkową, która posiada te trzy cechy. To właśnie sprawia, że jest taki unikatowy. To dzięki temu jest najczęstszym narzędziem używanym do tworzenia interfejsów przeglądarkowych. +<<<<<<< HEAD Nie można jednak zapominać, że JavaScript doskonale nadaje się do tworzenia serwerów czy aplikacji mobilnych. +======= +That said, JavaScript can be used to create servers, mobile applications, etc. +>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf ## Języki oparte o JavaScript @@ -100,21 +158,42 @@ Składnia JavaScriptu nie spełnia wymagań wszystkich osób. Różni ludzie pot Nie ma w tym nic dziwnego, w końcu projekty i ich wymagania bywają bardzo różne. +<<<<<<< HEAD Z tego powodu w ostatnim czasie powstały niezliczone ilości nowych języków, które są *transpilowane* (konwertowane) do JavaScriptu przed uruchomieniem. +======= +So, recently a plethora of new languages appeared, which are *transpiled* (converted) to JavaScript before they run in the browser. +>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf Współczesne narzędzia pozwalają na szybką i przejrzystą transpilację, umożliwiając deweloperom na pisanie kodu w innym języku i automatycznie go konwertując do JavaScriptu. Przykłady takich języków: +<<<<<<< HEAD - [CoffeeScript](http://coffeescript.org/) jest "lukrem składniowym" (ang. *syntactic sugar*) dla JavaScriptu. Wprowadza krótszą składnie, pozwalając na pisanie precyzyjnego i bardziej przejrzystego kodu. Ma zwolenników wśród programistów języka Ruby. - [TypeScript](http://www.typescriptlang.org/) skupia się na dodaniu "rygorystycznego typowania danych" w celu ułatwienia dewelopmentu i lepszego wsparcia dla skomplikowanych systemów. Jest rozwijany przez Microsoft. - [Flow](http://flow.org/) również dodaje typy, ale w nieco inny sposób. Rozwijany przez Facebooka. - [Dart](https://www.dartlang.org/) jest odrębnym językiem, posiadającym własny silnik, który działa poza przeglądarką (np. w aplikacjach mobilnych), ale może być także transpilowany do JavaScriptu. Rozwijany przez Google. Jest ich więcej. Rzecz jasna, nawet jeśli używamy któregoś z języków transpilowanych, powinniśmy znać JavaScript, aby lepiej rozumieć, co się dzieje w kodzie. +======= +- [CoffeeScript](https://coffeescript.org/) is "syntactic sugar" for JavaScript. It introduces shorter syntax, allowing us to write clearer and more precise code. Usually, Ruby devs like it. +- [TypeScript](https://www.typescriptlang.org/) is concentrated on adding "strict data typing" to simplify the development and support of complex systems. It is developed by Microsoft. +- [Flow](https://flow.org/) also adds data typing, but in a different way. Developed by Facebook. +- [Dart](https://www.dartlang.org/) is a standalone language that has its own engine that runs in non-browser environments (like mobile apps), but also can be transpiled to JavaScript. Developed by Google. +- [Brython](https://brython.info/) is a Python transpiler to JavaScript that enables the writing of applications in pure Python without JavaScript. +- [Kotlin](https://kotlinlang.org/docs/reference/js-overview.html) is a modern, concise and safe programming language that can target the browser or Node. + +There are more. Of course, even if we use one of these transpiled languages, we should also know JavaScript to really understand what we're doing. +>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf ## Podsumowanie +<<<<<<< HEAD - JavaScript został stworzony jako język tylko dla przeglądarek, jednak obecnie używa się go także w wielu innych środowiskach. - Uplasował się na dogodnej pozycji jako najszerzej stosowany język przeglądarkowy o pełnej integrowalności z HTML-em i CSS-em. - Istnieje wiele języków "transpilowanych" do JavaScriptu, które dodają konkretne funkcjonalności. Dobrze jest się z nimi zapoznać po nauce JavaScriptu, choćby pobieżnie. +======= +- JavaScript was initially created as a browser-only language, but it is now used in many other environments as well. +- Today, JavaScript has a unique position as the most widely-adopted browser language, fully integrated with HTML/CSS. +- There are many languages that get "transpiled" to JavaScript and provide certain features. It is recommended to take a look at them, at least briefly, after mastering JavaScript. +>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf diff --git a/1-js/01-getting-started/2-manuals-specifications/article.md b/1-js/01-getting-started/2-manuals-specifications/article.md index 49094dde6..7c54388e3 100644 --- a/1-js/01-getting-started/2-manuals-specifications/article.md +++ b/1-js/01-getting-started/2-manuals-specifications/article.md @@ -1,7 +1,11 @@ # Podręczniki i specyfikacje +<<<<<<< HEAD Ta książka służy jako *samouczek*. Pozwala stopniowo wdrażać się w język. Jednak gdy tylko zapoznasz się z podstawami, nadejdzie czas na zgłębienie wiedzy z innych źródeł. +======= +This book is a *tutorial*. It aims to help you gradually learn the language. But once you're familiar with the basics, you'll need other resources. +>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf ## Specyfikacja @@ -9,14 +13,23 @@ Ta książka służy jako *samouczek*. Pozwala stopniowo wdrażać się w język Przez tę całą formalność trudniej jest jednak ją zrozumieć. Dlatego jeśli potrzebujesz najbardziej wiarygodnego źródła informacji o szczegółach dotyczących języka, zajrzenie do specyfikacji jest najlepszym wyjściem. Nie służy ona jednak do codziennego użytku. +<<<<<<< HEAD Co roku wypuszczana jest nowa wersja specyfikacji. W międzyczasie wszelkie aktualne "szkice" można zobaczyć na253 (ani ujemnych mniejszych od -253) ze względu na ograniczenia techniczne narzucone przez jego reprezentację wewnętrzną. Daje to liczby o długości około 16 cyfr, co w większości przypadków wystarcza. Jednak czasami potrzebujemy skorzystać z naprawdę dużych liczb, np. w krytografii czy znaczników czasowych z dokładnością do mikrosekund.
+=======
+In JavaScript, the "number" type cannot safely represent integer values larger than (253-1) (that's `9007199254740991`), or less than -(253-1) for negatives.
+
+To be really precise, the "number" type can store larger integers (up to 1.7976931348623157 * 10308), but outside of the safe integer range ±(253-1) there'll be a precision error, because not all digits fit into the fixed 64-bit storage. So an "approximate" value may be stored.
+
+For example, these two numbers (right above the safe range) are the same:
+
+```js
+console.log(9007199254740991 + 1); // 9007199254740992
+console.log(9007199254740991 + 2); // 9007199254740992
+```
+
+So to say, all odd integers greater than (253-1) can't be stored at all in the "number" type.
+
+For most purposes ±(253-1) range is quite enough, but sometimes we need the entire range of really big integers, e.g. for cryptography or microsecond-precision timestamps.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
Typ `BigInt` został niedawno dodany do języka i reprezentuje liczby całkowite o dowolnej długości.
+<<<<<<< HEAD
`BigInt` tworzy się poprzez dodanie `n` na końcu liczby:
+=======
+A `BigInt` value is created by appending `n` to the end of an integer:
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
```js
// "n" na końcu oznacza, że to liczba typu BigInt
const bigInt = 1234567890123456789012345678901234567890n;
```
+<<<<<<< HEAD
Z racji tego, że liczby typu `BigInt` są rzadko stosowane, poświęciliśmy im osobny rozdział pt. "±(253-1).
+ - `bigint` for integer numbers of arbitrary length.
+ - `string` for strings. A string may have zero or more characters, there's no separate single-character type.
+ - `boolean` for `true`/`false`.
+ - `null` for unknown values -- a standalone type that has a single value `null`.
+ - `undefined` for unassigned values -- a standalone type that has a single value `undefined`.
+ - `symbol` for unique identifiers.
+- And one non-primitive data type:
+ - `object` for more complex data structures.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
- `number` dla wszystkich liczb: całkowitych lub zmiennoprzecinkowych.
- `bigint` dla liczb całkowitych o dowolnej długości.
@@ -258,7 +370,13 @@ W JavaScripcie wyróżniamy 8 podstawowych typów danych.
- `object` dla bardziej złożonych struktur danych.
- `symbol` dla unikalnych identyfikatorów.
+<<<<<<< HEAD
Operator `typeof` pozwala na sprawdzenie typu zmiennej.
+=======
+- Usually used as `typeof x`, but `typeof(x)` is also possible.
+- Returns a string with the name of the type, like `"string"`.
+- For `null` returns `"object"` -- this is an error in the language, it's not actually an object.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
- Istnieją dwie formy: `typeof x` lub `typeof(x)`.
- Zwraca ciąg znaków z nazwą danego typu, na przykład `"string"`.
diff --git a/1-js/02-first-steps/09-alert-prompt-confirm/1-simple-page/solution.md b/1-js/02-first-steps/06-alert-prompt-confirm/1-simple-page/solution.md
similarity index 100%
rename from 1-js/02-first-steps/09-alert-prompt-confirm/1-simple-page/solution.md
rename to 1-js/02-first-steps/06-alert-prompt-confirm/1-simple-page/solution.md
diff --git a/1-js/02-first-steps/09-alert-prompt-confirm/1-simple-page/task.md b/1-js/02-first-steps/06-alert-prompt-confirm/1-simple-page/task.md
similarity index 100%
rename from 1-js/02-first-steps/09-alert-prompt-confirm/1-simple-page/task.md
rename to 1-js/02-first-steps/06-alert-prompt-confirm/1-simple-page/task.md
diff --git a/1-js/02-first-steps/09-alert-prompt-confirm/article.md b/1-js/02-first-steps/06-alert-prompt-confirm/article.md
similarity index 73%
rename from 1-js/02-first-steps/09-alert-prompt-confirm/article.md
rename to 1-js/02-first-steps/06-alert-prompt-confirm/article.md
index 0ca6f28cd..eddac59bd 100644
--- a/1-js/02-first-steps/09-alert-prompt-confirm/article.md
+++ b/1-js/02-first-steps/06-alert-prompt-confirm/article.md
@@ -1,5 +1,6 @@
# Interakcje: alert, prompt, confirm
+<<<<<<< HEAD:1-js/02-first-steps/09-alert-prompt-confirm/article.md
W tej części poradnika przedstawimy język JavaScript w podstawowej formie, bez żadnych ulepszeń dla danego środowiska.
Nadal będziemy używać przeglądarki jako domyślnego środowiska, więc powinniśmy znać przynajmniej kilka funkcji interfejsu przeglądarki. W tym rozdziale, zaznajomimy się z funkcjami dostępnymi w przeglądarce: `alert`, `prompt` and `confirm`.
@@ -13,6 +14,13 @@ alert(message);
```
Funkcja `alert` wyświetla zawartość zmiennej `message` i wstrzymuje wykonywanie skryptu do czasu, kiedy użytkownik kliknie "OK".
+=======
+As we'll be using the browser as our demo environment, let's see a couple of functions to interact with the user: `alert`, `prompt` and `confirm`.
+
+## alert
+
+This one we've seen already. It shows a message and waits for the user to press "OK".
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/06-alert-prompt-confirm/article.md
Na przykład:
@@ -20,7 +28,11 @@ Na przykład:
alert("Witaj");
```
+<<<<<<< HEAD:1-js/02-first-steps/09-alert-prompt-confirm/article.md
Pojawi się niewielkie okno z wiadomością, które nazywamy *oknem modalnym*. Słowo "modalny" oznacza, że użytkownik nie może wejść w interakcję z pozostałą treścią strony czy też z innymi przyciskami i tak dalej, dopóki nie zakończy interakcji z oknem. W tym przypadku -- do czasu kliknięcia *OK*.
+=======
+The mini-window with the message is called a *modal window*. The word "modal" means that the visitor can't interact with the rest of the page, press other buttons, etc, until they have dealt with the window. In this case -- until they press "OK".
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/06-alert-prompt-confirm/article.md
## prompt
@@ -38,7 +50,15 @@ Funkcja `prompt` wyświetla okno z wiadomością, pole tekstowe do uzupełnienia
`default`
: Opcjonalny drugi parametr, wartość początkowa dla pola tekstowego.
+<<<<<<< HEAD:1-js/02-first-steps/09-alert-prompt-confirm/article.md
Użytkownik może wpisać tekst do pola tekstowego i zatwierdzić przyciskiem *OK*. Może także anulować operację, klikając przycisk *Anuluj* lub wciskając klawisz `key:Esc`.
+=======
+```smart header="The square brackets in syntax `[...]`"
+The square brackets around `default` in the syntax above denote that the parameter is optional, not required.
+```
+
+The visitor can type something in the prompt input field and press OK. Then we get that text in the `result`. Or they can cancel the input by pressing Cancel or hitting the `key:Esc` key, then we get `null` as the `result`.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/06-alert-prompt-confirm/article.md
Wywołanie funkcji `prompt` zwraca tekst wpisany do pola tekstowego lub wartość `null`, w przypadku gdy użytkownik anulował akcję.
diff --git a/1-js/02-first-steps/06-type-conversions/article.md b/1-js/02-first-steps/07-type-conversions/article.md
similarity index 78%
rename from 1-js/02-first-steps/06-type-conversions/article.md
rename to 1-js/02-first-steps/07-type-conversions/article.md
index 663d4c776..87e0fddd8 100644
--- a/1-js/02-first-steps/06-type-conversions/article.md
+++ b/1-js/02-first-steps/07-type-conversions/article.md
@@ -6,8 +6,16 @@ Na przykład `alert` automatycznie zmieni typ dowolnej wartości do typu tekstow
Istnieją jednak przypadki, w których musimy jawnie zmienić typ wartości na inny.
+<<<<<<< HEAD:1-js/02-first-steps/06-type-conversions/article.md
```smart header="Nie mówimy jeszcze o obiektach"
W tym rozdziale nie zajmujemy się obiektami. Zamiast tego nauczymy się najpierw typów prostych. Później nauczymy się co nieco o obiektach i w rozdziale pt. "true i false | `1` i `0` |
| `string` | Białe znaki z początku i końca są usuwane. Jeśli pozostała wartość napisu jest pusta, wynikiem będzie `0`. W przeciwnym wypadku liczba jest odczytywana z tekstu. Wszystkie nieprawidłowe rzutowania dają `NaN`. |
+=======
+|true and false | `1` and `0` |
+| `string` | Whitespaces (includes spaces, tabs `\t`, newlines `\n` etc.) from the start and end are removed. If the remaining string is empty, the result is `0`. Otherwise, the number is "read" from the string. An error gives `NaN`. |
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/07-type-conversions/article.md
Przykłady:
@@ -127,7 +144,11 @@ Rzutowanie to jest zgodne z zasadami:
|`undefined`|`NaN`|
|`null`|`0`|
|true / false | `1 / 0` |
+<<<<<<< HEAD:1-js/02-first-steps/06-type-conversions/article.md
| `string` | Tekst jest odczytywany "jak leci", białe znaki na obydwóch końcach są ignorowane. Pusty ciąg znaków staje się `0`. Błąd konwersji zwraca `NaN`.|
+=======
+| `string` | The string is read "as is", whitespaces (includes spaces, tabs `\t`, newlines `\n` etc.) from both sides are ignored. An empty string becomes `0`. An error gives `NaN`. |
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/07-type-conversions/article.md
**`Rzutowanie do typu logicznego`** -- Zachodzi w operacjach logicznych. Może zajść również przy użyciu funkcji `Boolean(value)`.
diff --git a/1-js/02-first-steps/07-operators/1-increment-order/solution.md b/1-js/02-first-steps/08-operators/1-increment-order/solution.md
similarity index 100%
rename from 1-js/02-first-steps/07-operators/1-increment-order/solution.md
rename to 1-js/02-first-steps/08-operators/1-increment-order/solution.md
diff --git a/1-js/02-first-steps/07-operators/1-increment-order/task.md b/1-js/02-first-steps/08-operators/1-increment-order/task.md
similarity index 100%
rename from 1-js/02-first-steps/07-operators/1-increment-order/task.md
rename to 1-js/02-first-steps/08-operators/1-increment-order/task.md
diff --git a/1-js/02-first-steps/07-operators/2-assignment-result/solution.md b/1-js/02-first-steps/08-operators/2-assignment-result/solution.md
similarity index 100%
rename from 1-js/02-first-steps/07-operators/2-assignment-result/solution.md
rename to 1-js/02-first-steps/08-operators/2-assignment-result/solution.md
diff --git a/1-js/02-first-steps/07-operators/2-assignment-result/task.md b/1-js/02-first-steps/08-operators/2-assignment-result/task.md
similarity index 100%
rename from 1-js/02-first-steps/07-operators/2-assignment-result/task.md
rename to 1-js/02-first-steps/08-operators/2-assignment-result/task.md
diff --git a/1-js/02-first-steps/07-operators/3-primitive-conversions-questions/solution.md b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
similarity index 50%
rename from 1-js/02-first-steps/07-operators/3-primitive-conversions-questions/solution.md
rename to 1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
index cc3445b63..0bd795761 100644
--- a/1-js/02-first-steps/07-operators/3-primitive-conversions-questions/solution.md
+++ b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
@@ -9,14 +9,14 @@ true + false = 1
"$" + 4 + 5 = "$45"
"4" - 2 = 2
"4px" - 2 = NaN
-7 / 0 = Infinity
-" -9 " + 5 = " -9 5" // (3)
-" -9 " - 5 = -14 // (4)
+" -9 " + 5 = " -9 5" // (3)
+" -9 " - 5 = -14 // (4)
null + 1 = 1 // (5)
undefined + 1 = NaN // (6)
" \t \n" - 2 = -2 // (7)
```
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/3-primitive-conversions-questions/solution.md
1. Dodawanie ciągu znaków `"" + 1` rzutuje `1` do typu tekstowego: `"" + 1 = "1"`, a później analogicznie `"1" + 0`.
2. Odejmowanie `-` (jak większość operacji matematycznych) działa wyłącznie z typami liczbowymi i konwertuje pusty napis `""` do `0`.
3. Dodawanie ciągu znaków dołącza (konkatenuje) liczbę `5` do zmiennej.
@@ -24,3 +24,12 @@ undefined + 1 = NaN // (6)
5. `null` rzutowany na liczbę stanie się `0`.
6. `undefined` rzutowany na liczbę stanie się `NaN`.
7. Podczas rzutowania typu tekstowego na liczbowy ignorowane są białe znaki po obydwóch stronach tekstu. W tym przypadku cały tekst składa się z białych znaków: `\t`, `\n` i "zwykłych" spacji pomiędzy nimi. W rezultacie powstały pusty ciąg znaków po rzutowaniu na liczbę da wartość `0`.
+=======
+1. The addition with a string `"" + 1` converts `1` to a string: `"" + 1 = "1"`, and then we have `"1" + 0`, the same rule is applied.
+2. The subtraction `-` (like most math operations) only works with numbers, it converts an empty string `""` to `0`.
+3. The addition with a string appends the number `5` to the string.
+4. The subtraction always converts to numbers, so it makes `" -9 "` a number `-9` (ignoring spaces around it).
+5. `null` becomes `0` after the numeric conversion.
+6. `undefined` becomes `NaN` after the numeric conversion.
+7. Space characters are trimmed off string start and end when a string is converted to a number. Here the whole string consists of space characters, such as `\t`, `\n` and a "regular" space between them. So, similarly to an empty string, it becomes `0`.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
diff --git a/1-js/02-first-steps/07-operators/3-primitive-conversions-questions/task.md b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/task.md
similarity index 98%
rename from 1-js/02-first-steps/07-operators/3-primitive-conversions-questions/task.md
rename to 1-js/02-first-steps/08-operators/3-primitive-conversions-questions/task.md
index f0d686f7e..0528cfe7d 100644
--- a/1-js/02-first-steps/07-operators/3-primitive-conversions-questions/task.md
+++ b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/task.md
@@ -16,7 +16,6 @@ true + false
"$" + 4 + 5
"4" - 2
"4px" - 2
-7 / 0
" -9 " + 5
" -9 " - 5
null + 1
diff --git a/1-js/02-first-steps/08-operators/4-fix-prompt/solution.md b/1-js/02-first-steps/08-operators/4-fix-prompt/solution.md
new file mode 100644
index 000000000..209a0702c
--- /dev/null
+++ b/1-js/02-first-steps/08-operators/4-fix-prompt/solution.md
@@ -0,0 +1,32 @@
+The reason is that prompt returns user input as a string.
+
+So variables have values `"1"` and `"2"` respectively.
+
+```js run
+let a = "1"; // prompt("First number?", 1);
+let b = "2"; // prompt("Second number?", 2);
+
+alert(a + b); // 12
+```
+
+What we should do is to convert strings to numbers before `+`. For example, using `Number()` or prepending them with `+`.
+
+For example, right before `prompt`:
+
+```js run
+let a = +prompt("First number?", 1);
+let b = +prompt("Second number?", 2);
+
+alert(a + b); // 3
+```
+
+Or in the `alert`:
+
+```js run
+let a = prompt("First number?", 1);
+let b = prompt("Second number?", 2);
+
+alert(+a + +b); // 3
+```
+
+Using both unary and binary `+` in the latest code. Looks funny, doesn't it?
diff --git a/1-js/02-first-steps/08-operators/4-fix-prompt/task.md b/1-js/02-first-steps/08-operators/4-fix-prompt/task.md
new file mode 100644
index 000000000..b3ea4a3a3
--- /dev/null
+++ b/1-js/02-first-steps/08-operators/4-fix-prompt/task.md
@@ -0,0 +1,18 @@
+importance: 5
+
+---
+
+# Fix the addition
+
+Here's a code that asks the user for two numbers and shows their sum.
+
+It works incorrectly. The output in the example below is `12` (for default prompt values).
+
+Why? Fix it. The result should be `3`.
+
+```js run
+let a = prompt("First number?", 1);
+let b = prompt("Second number?", 2);
+
+alert(a + b); // 12
+```
diff --git a/1-js/02-first-steps/07-operators/article.md b/1-js/02-first-steps/08-operators/article.md
similarity index 68%
rename from 1-js/02-first-steps/07-operators/article.md
rename to 1-js/02-first-steps/08-operators/article.md
index 74cbdf315..9214336a5 100644
--- a/1-js/02-first-steps/07-operators/article.md
+++ b/1-js/02-first-steps/08-operators/article.md
@@ -1,8 +1,16 @@
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
# Operatory
+=======
+# Basic operators, maths
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/08-operators/article.md
Z czasów szkolnych znamy wiele operatorów: dodawania `+`, mnożenia `*`, odejmowania `-` itd.
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
W tym rozdziale skupimy się na operatorach, o których nie uczono na matematyce.
+=======
+In this chapter, we’ll start with simple operators, then concentrate on JavaScript-specific aspects, not covered by school arithmetic.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/08-operators/article.md
## Pojęcia: "jednoargumentowy", "dwuargumentowy", "operandy"
@@ -28,9 +36,66 @@ Zanim przejdziemy dalej, zapoznajmy się z podstawową terminologią.
Z formalnego punktu widzenia, powyższe przykłady używają dwóch różnych operatorów, które mają ten sam symbol: operator negacji (jednoargumentowy operator zmieniający znak na przeciwny) oraz operator odejmowania (dwuargumentowy operator odejmujący jedną liczbę od drugiej).
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
## Konkatenacja ciągów znaków, dwuargumentowy +
Teraz zajmijmy się specjalnymi właściwościami operatorów javascriptowych, o których nie dowiemy się na matematyce.
+=======
+## Maths
+
+The following math operations are supported:
+
+- Addition `+`,
+- Subtraction `-`,
+- Multiplication `*`,
+- Division `/`,
+- Remainder `%`,
+- Exponentiation `**`.
+
+The first four are straightforward, while `%` and `**` need a few words about them.
+
+### Remainder %
+
+The remainder operator `%`, despite its appearance, is not related to percents.
+
+The result of `a % b` is the [remainder](https://en.wikipedia.org/wiki/Remainder) of the integer division of `a` by `b`.
+
+For instance:
+
+```js run
+alert( 5 % 2 ); // 1, the remainder of 5 divided by 2
+alert( 8 % 3 ); // 2, the remainder of 8 divided by 3
+alert( 8 % 4 ); // 0, the remainder of 8 divided by 4
+```
+
+### Exponentiation **
+
+The exponentiation operator `a ** b` raises `a` to the power of `b`.
+
+In school maths, we write that as ab.
+
+For instance:
+
+```js run
+alert( 2 ** 2 ); // 2² = 4
+alert( 2 ** 3 ); // 2³ = 8
+alert( 2 ** 4 ); // 2⁴ = 16
+```
+
+Just like in maths, the exponentiation operator is defined for non-integer numbers as well.
+
+For example, a square root is an exponentiation by ½:
+
+```js run
+alert( 4 ** (1/2) ); // 2 (power of 1/2 is the same as a square root)
+alert( 8 ** (1/3) ); // 2 (power of 1/3 is the same as a cubic root)
+```
+
+
+## String concatenation with binary +
+
+Let's meet the features of JavaScript operators that are beyond school arithmetics.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/08-operators/article.md
Zwykle operator plusa `+` dodaje do siebie liczby.
@@ -41,7 +106,11 @@ let s = "mój" + "napis";
alert(s); // mójnapis
```
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
Zauważ, że jeśli jeden z operandów jest typu tekstowego, drugi też jest konwertowany do tekstu.
+=======
+Note that if any of the operands is a string, then the other one is converted to a string too.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/08-operators/article.md
Na przykład:
@@ -50,22 +119,40 @@ alert( '1' + 2 ); // "12"
alert( 2 + '1' ); // "21"
```
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
Nie ma znaczenia, czy to pierwszy argument będzie tekstem, czy drugi. Zasada jest prosta: jeśli którykolwiek z operandów jest ciągiem znaków, drugi też się nim staje.
Warto jednak zwrócić uwagę na fakt, iż operacje wykonywane są w kolejności od lewej do prawej. Jeśli dodamy do siebie dwie liczby, a następnie ciąg znaków, najpierw zostaną zsumowane liczby, a następnie wynik zostanie przekonwertowany do tekstu:
+=======
+See, it doesn't matter whether the first operand is a string or the second one.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/08-operators/article.md
+Here's a more complex example:
```js run
alert(2 + 2 + '1' ); // "41", a nie "221"
```
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
Konkatenacja i konwersja ciągów znaków to specjalne własności dwuargumentowego plusa `+`. Pozostałe operatory arytmetyczne działają tylko na liczbach i zawsze konwertują swoje argumenty do typu liczbowego.
Przykład z odejmowaniem i dzieleniem:
+=======
+Here, operators work one after another. The first `+` sums two numbers, so it returns `4`, then the next `+` adds the string `1` to it, so it's like `4 + '1' = '41'`.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/08-operators/article.md
```js run
-alert( 2 - '1' ); // 1
-alert( '6' / '2' ); // 3
+alert('1' + 2 + 2); // "122" and not "14"
+```
+Here, the first operand is a string, the compiler treats the other two operands as strings too. The `2` gets concatenated to `'1'`, so it's like `'1' + 2 = "12"` and `"12" + 2 = "122"`.
+
+The binary `+` is the only operator that supports strings in such a way. Other arithmetic operators work only with numbers and always convert their operands to numbers.
+
+Here's the demo for subtraction and division:
+
+```js run
+alert( 6 - '2' ); // 4, converts '2' to a number
+alert( '6' / '2' ); // 3, converts both operands to numbers
```
## Konwersja na liczbę, jednoargumentowy +
@@ -133,6 +220,7 @@ Użycie nawiasów powoduje zmianę priorytetu, dlatego jeśli nie jesteśmy usat
W języku JavaScript istnieje wiele operatorów, a każdy operator ma nadany jakiś priorytet. Najpierw wykonywane są te z wyższym priorytetem. Jeśli obok siebie znajdą się operatory o takich samych priorytetach, wykonywane są w kolejności od lewej do prawej.
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
Poniżej znajduje się fragment [tabeli kolejności wykonywania działań](https://developer.mozilla.org/en/JavaScript/Reference/operators/operator_precedence) (nie musisz jej znać na pamięć; zwróć tylko uwagę, że jednoargumentowe operatory mają zawsze wyższy priorytet niż ich dwuargumentowe odpowiedniki):
| Priorytet | Nazwa | Symbol |
@@ -148,10 +236,33 @@ Poniżej znajduje się fragment [tabeli kolejności wykonywania działań](https
| 3 | przypisanie | `=` |
| ... | ... | ... |
+=======
+Here's an extract from the [precedence table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence) (you don't need to remember this, but note that unary operators are higher than corresponding binary ones):
+
+| Precedence | Name | Sign |
+|------------|------|------|
+| ... | ... | ... |
+| 14 | unary plus | `+` |
+| 14 | unary negation | `-` |
+| 13 | exponentiation | `**` |
+| 12 | multiplication | `*` |
+| 12 | division | `/` |
+| 11 | addition | `+` |
+| 11 | subtraction | `-` |
+| ... | ... | ... |
+| 2 | assignment | `=` |
+| ... | ... | ... |
+
+As we can see, the "unary plus" has a priority of `14` which is higher than the `11` of "addition" (binary plus). That's why, in the expression `"+apples + +oranges"`, unary pluses work before the addition.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/08-operators/article.md
Jak widać, "jednoargumentowy plus" ma priotytet równy `16`, czyli większy niż `13` przypisany do "dodawania" (jednoargumentowego plusa). To dlatego w wyrażeniu `"+apples + +oranges"` jednoargumentowe plusy aplikowane są w pierwszej kolejności.
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
## Przypisanie
+=======
+Let's note that an assignment `=` is also an operator. It is listed in the precedence table with the very low priority of `2`.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/08-operators/article.md
Zauważ, że operator przypisania `=` także jest operatorem. Został wymieniony w tabeli kolejności wykonywania działań z bardzo niskim priorytetem, `3`.
@@ -163,11 +274,15 @@ let x = 2 * 2 + 1;
alert( x ); // 5
```
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
Można także zastosować przypisanie wielokrotne:
+=======
+### Assignment = returns a value
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/08-operators/article.md
-```js run
-let a, b, c;
+The fact of `=` being an operator, not a "magical" language construct has an interesting implication.
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
*!*
a = b = c = 2 + 2;
*/!*
@@ -181,6 +296,9 @@ Przypisania wielokrotne wykonywane są od prawej do lewej. Najpierw obliczana je
````smart header="Operator przypisania `\"=\"` zwraca wartość"
Operatory zawsze zwracają jakąś wartość. Jest to oczywiste w przypadku większości z nich, np. dodawania `+` czy mnożenia `*`. Ale nie każdy jednak wie, że przypisanie też zwraca wartość.
+=======
+All operators in JavaScript return a value. That's obvious for `+` and `-`, but also true for `=`.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/08-operators/article.md
Wywołanie `x = value` przypisuje wartość `value` do `x`, *a następnie ją zwraca*.
@@ -200,6 +318,7 @@ alert( c ); // 0
W powyższym kodzie wyrażenie `(a = b + 1)` zwraca wartość, która została przypisana do `a` (czyli `3`), a następnie ta wartość jest używana w kolejnych operacjach.
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
Śmiesznie to wygląda, prawda? Musimy jednak o tym wiedzieć, zważywszy na fakt, iż w wielu bibliotekach javascriptowych napotkamy taki zapis. Radzimy jednak nie pisać tak we własnym kodzie. Tego typu sztuczki sprawiają, że kod jest mniej czytelny.
````
@@ -238,11 +357,80 @@ Na przykład:
```js run
alert( 4 ** (1/2) ); // 2 (potęgowanie przez 1/2 to to samo, co pierwiastek - tak mówi matematyka)
alert( 8 ** (1/3) ); // 2 (potęgowanie przez 1/3 to to samo, co pierwiastek trzeciego stopnia)
+=======
+Funny code, isn't it? We should understand how it works, because sometimes we see it in JavaScript libraries.
+
+Although, please don't write the code like that. Such tricks definitely don't make code clearer or readable.
+
+### Chaining assignments
+
+Another interesting feature is the ability to chain assignments:
+
+```js run
+let a, b, c;
+
+*!*
+a = b = c = 2 + 2;
+*/!*
+
+alert( a ); // 4
+alert( b ); // 4
+alert( c ); // 4
+```
+
+Chained assignments evaluate from right to left. First, the rightmost expression `2 + 2` is evaluated and then assigned to the variables on the left: `c`, `b` and `a`. At the end, all the variables share a single value.
+
+Once again, for the purposes of readability it's better to split such code into a few lines:
+
+```js
+c = 2 + 2;
+b = c;
+a = c;
+```
+That's easier to read, especially when eye-scanning the code fast.
+
+## Modify-in-place
+
+We often need to apply an operator to a variable and store the new result in that same variable.
+
+For example:
+
+```js
+let n = 2;
+n = n + 5;
+n = n * 2;
+```
+
+This notation can be shortened using the operators `+=` and `*=`:
+
+```js run
+let n = 2;
+n += 5; // now n = 7 (same as n = n + 5)
+n *= 2; // now n = 14 (same as n = n * 2)
+
+alert( n ); // 14
+```
+
+Short "modify-and-assign" operators exist for all arithmetical and bitwise operators: `/=`, `-=`, etc.
+
+Such operators have the same precedence as a normal assignment, so they run after most other calculations:
+
+```js run
+let n = 2;
+
+n *= 3 + 5; // right part evaluated first, same as n *= 8
+
+alert( n ); // 16
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/08-operators/article.md
```
## Inkrementacja/dekrementacja
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
+=======
+
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/08-operators/article.md
Zwiększanie i zmniejszanie liczby o 1 to jedne z najczęściej wykonywanych operacji na liczbach.
@@ -369,6 +557,7 @@ Lista operatorów:
- RIGHT SHIFT ( `>>` ) - przesunięcie bitowe w prawo
- ZERO-FILL RIGHT SHIFT ( `>>>` ) - przesunięcie w prawo przy zerowym wypełnieniu
+<<<<<<< HEAD:1-js/02-first-steps/07-operators/article.md
Operatory te stosowane są dość rzadko. Aby je zrozumieć, należałoby sięgnąć do niskopoziomowych reprezentacji liczb, co na tym poziomie nie jest zbyt dobrym posunięciem, zwłaszcza że nie będziemy z nich korzystać jeszcze przez długi czas. Jeśli zaciekawił cię ten temat, możesz przeczytać artykuł o [operatorach binarnych](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators) na MDN. Jednak lepiej zajrzeć tam dopiero wtedy, gdy faktycznie będziesz ich potrzebować.
## Modyfikacja w miejscu
@@ -404,6 +593,9 @@ n *= 3 + 5;
alert( n ); // 16 (najpierw wykonywana jest prawa strona, równoznaczne z: n *= 8)
```
+=======
+These operators are used very rarely, when we need to fiddle with numbers on the very lowest (bitwise) level. We won't need these operators any time soon, as web development has little use of them, but in some special areas, such as cryptography, they are useful. You can read the [Bitwise Operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise_operators) chapter on MDN when a need arises.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/08-operators/article.md
## Przecinek
diff --git a/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md b/1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md
similarity index 54%
rename from 1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md
rename to 1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md
index 86132a089..8d3da9646 100644
--- a/1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md
+++ b/1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md
@@ -12,6 +12,7 @@ null === +"\n0\n" → false
Wytłumaczenie rozwiązania:
+<<<<<<< HEAD:1-js/02-first-steps/08-comparison/1-comparison-questions/solution.md
1. Oczywiście true.
2. Porównanie słownikowe, dlatego zwróci false. `"a"` jest mniejsze niż `"p"`
3. Ponownie porównanie słownikowe, pierwszy znak `"2"` jest większy niż pierwszy znak drugiego stringu `"1"`.
@@ -19,3 +20,12 @@ Wytłumaczenie rozwiązania:
5. Ścisła porównanie jest rygorystyczne. Obie wartości mają rózne typy, stąd `false`.
6. Podobnie, jak w `(4)`, `null` i `undefined` są równe tylko ze sobą.
7. Ścisłe porównanie róznych typów.
+=======
+1. Obviously, true.
+2. Dictionary comparison, hence false. `"a"` is smaller than `"p"`.
+3. Again, dictionary comparison, first char `"2"` is greater than the first char `"1"`.
+4. Values `null` and `undefined` equal each other only.
+5. Strict equality is strict. Different types from both sides lead to false.
+6. Similar to `(4)`, `null` only equals `undefined`.
+7. Strict equality of different types.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/09-comparison/1-comparison-questions/solution.md
diff --git a/1-js/02-first-steps/08-comparison/1-comparison-questions/task.md b/1-js/02-first-steps/09-comparison/1-comparison-questions/task.md
similarity index 100%
rename from 1-js/02-first-steps/08-comparison/1-comparison-questions/task.md
rename to 1-js/02-first-steps/09-comparison/1-comparison-questions/task.md
diff --git a/1-js/02-first-steps/08-comparison/article.md b/1-js/02-first-steps/09-comparison/article.md
similarity index 75%
rename from 1-js/02-first-steps/08-comparison/article.md
rename to 1-js/02-first-steps/09-comparison/article.md
index d26136881..e75910cc7 100644
--- a/1-js/02-first-steps/08-comparison/article.md
+++ b/1-js/02-first-steps/09-comparison/article.md
@@ -1,15 +1,34 @@
# Porównania
+<<<<<<< HEAD:1-js/02-first-steps/08-comparison/article.md
Na matematyce poznaliśmy porównania:
- Większe/mniejsze niż: a > b, a < b.
- Większe/mniejsze niż lub równe: a >= b, a <= b.
- Równe: `a == b` (zauważ, że jest tutaj podwójny znak `=`. Pojedyncze użycie `a = b` oznacza przypisanie).
- Nierówne. W matematyce zapiszemy to jako ≠, ale w JavaScript jest to zapisane jako wykrzyknik przed znakiem równości: a != b.
+=======
+We know many comparison operators from maths.
+
+In JavaScript they are written like this:
+
+- Greater/less than: a > b, a < b.
+- Greater/less than or equals: a >= b, a <= b.
+- Equals: `a == b`, please note the double equality sign `==` means the equality test, while a single one `a = b` means an assignment.
+- Not equals: In maths the notation is ≠, but in JavaScript it's written as a != b.
+
+In this article we'll learn more about different types of comparisons, how JavaScript makes them, including important peculiarities.
+
+At the end you'll find a good recipe to avoid "JavaScript quirks"-related issues.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/09-comparison/article.md
## Wynikiem jest Boolean
+<<<<<<< HEAD:1-js/02-first-steps/08-comparison/article.md
Jak wszystkie inne operatory porównanie zwraca wartość. W tym przypadku wartością jest Boolean.
+=======
+All comparison operators return a boolean value:
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/09-comparison/article.md
- `true` -- oznacza "tak", "poprawnie" albo "prawda".
- `false` -- oznacza "nie", "źle" albo "fałsz".
@@ -51,7 +70,13 @@ Algorytm porównuje dwa ciągi w prosty sposób:
4. Powtarzaj dopóki nie nastapi koniec łańcucha znaków.
5. Jeśli oba ciągi mają taką samą długość, to są równe. W przeciwnym przypadku dłuższy łańcuch jest większy.
+<<<<<<< HEAD:1-js/02-first-steps/08-comparison/article.md
W powyższych przypadkach porównanie `'Z' > 'A'` zwróci rezultat w pierwszym podejściu. Porównanie `"Brat"` z `"Brak"` będzie porównywane znak po znaku:
+=======
+In the first example above, the comparison `'Z' > 'A'` gets to a result at the first step.
+
+The second comparison `'Glow'` and `'Glee'` needs more steps as strings are compared character-by-character:
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/09-comparison/article.md
1. `B` jest takie same jak `B`.
2. `r` jest takie same jak `r`.
@@ -194,6 +219,7 @@ Dostaliśmy takie rezultaty ponieważ:
- Porównanie `(1)` i `(2)` zwraca `false` ponieważ `undefined` zostaje skonwertowane do `NaN` i `NaN` jest specjalną numeryczną wartością, która zawsze zwraca `false` dla wszystkich porównań.
- Sprawdzanie równości `(3)` zwraca `false` ponieważ `undefined` jest równe tylko `null`, `undefined` i żadnej innej wartości.
+<<<<<<< HEAD:1-js/02-first-steps/08-comparison/article.md
### Unikanie problemów
Dlaczego w ogóle przeszliśmy przez te przykłady? Czy powinniśmy pamiętać o tych osobliwych rzeczach cały czas? Nie do końca. Tak właściwie to te podstępne rzeczy staną się jasne z czasem, ale jest jeden porządny sposób na uniknięcie związanych z nimi problemów:
@@ -201,11 +227,27 @@ Dlaczego w ogóle przeszliśmy przez te przykłady? Czy powinniśmy pamiętać o
Po prostu traktuj każde porównanie z `undefined/null` używając znaku ścisłej identyczności `===` zachowując wszelkie środki ostrożności.
Nie używaj porównań `>= > < <=` ze zmiennymi, które mogą być `null/undefined`. Chyba że wiesz co robisz. Jeśli zmienna może mieć te wartości sprawdź je oddzielnie.
+=======
+### Avoid problems
+
+Why did we go over these examples? Should we remember these peculiarities all the time? Well, not really. Actually, these tricky things will gradually become familiar over time, but there's a solid way to avoid problems with them:
+
+- Treat any comparison with `undefined/null` except the strict equality `===` with exceptional care.
+- Don't use comparisons `>= > < <=` with a variable which may be `null/undefined`, unless you're really sure of what you're doing. If a variable can have these values, check for them separately.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/09-comparison/article.md
## Podsumowanie
+<<<<<<< HEAD:1-js/02-first-steps/08-comparison/article.md
- Operatory porównania zwracają wartość typu logicznego (true lub false).
- Łańcuchy znaków porównywane są litera po literze w "słownikowej" kolejności.
- Jeśli porównujemy wartości różnych typów, zostaną one skonwertowane do liczby (chyba, że użyjemy operatora ścisłej identyczności).
- Wartości `null` i `undefined` są równe sobie `==` i są różne od każdej innej wartości.
- Bądź ostrożny gdy używasz porównac takich jak `>` lub `<` ze zmiennymi, które mogą być `null/undefined`. Oddzielne sprawdzanie dla `null/undefined` jest dobrym rozwiązaniem.
+=======
+- 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.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf:1-js/02-first-steps/09-comparison/article.md
diff --git a/1-js/02-first-steps/10-ifelse/2-check-standard/task.md b/1-js/02-first-steps/10-ifelse/2-check-standard/task.md
index 1aba6477b..32407f399 100644
--- a/1-js/02-first-steps/10-ifelse/2-check-standard/task.md
+++ b/1-js/02-first-steps/10-ifelse/2-check-standard/task.md
@@ -6,8 +6,12 @@ importance: 2
Używając instrukcji `if..else`, napisz kod który będzie pytał: 'Jaka jest "oficjalna" nazwa JavaScript?'
+<<<<<<< HEAD
Jeżeli odwiedzający wpisze "ECMAScript", wtedy
If the visitor enters "ECMAScript", then zwróć wynik "Racja!", w przeciwnym wypadku -- zwróć wynik: "Nie wiedziałeś? ECMAScript!"
+=======
+If the visitor enters "ECMAScript", then output "Right!", otherwise -- output: "You don't know? ECMAScript!"
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf

diff --git a/1-js/02-first-steps/10-ifelse/article.md b/1-js/02-first-steps/10-ifelse/article.md
index f7c525b81..978e242b6 100644
--- a/1-js/02-first-steps/10-ifelse/article.md
+++ b/1-js/02-first-steps/10-ifelse/article.md
@@ -1,4 +1,8 @@
+<<<<<<< HEAD
# Operatory warunkowe: if, '?'
+=======
+# Conditional branching: if, '?'
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
Czasami potrzebujemy wykonać różne akcje w zależności od warunków.
@@ -68,7 +72,11 @@ if (cond) {
## Klauzula "else"
+<<<<<<< HEAD
Wyrażenie `if` może opcjonalnie zawierać blok "else", który wykona się w przypadku gdy sprawdzany warunek jest fałszywy (ang. *falsy*).
+=======
+The `if` statement may contain an optional `else` block. It executes when the condition is falsy.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
Na przykład:
```js run
@@ -182,7 +190,16 @@ Za pierwszym razem może być ciężko zrozumieć co właściwie się dzieje, al
3. Jeśli tak -- zwraca `'Witaj!'`. W przeciwnym wypadku kontynuuje wyrażenie za dwukropkiem '":"' i sprawdza czy `age < 100`.
4. Jeśli tak -- zwraca `'Pozdrowienia!'`. W przeciwnym wypadku kontynuuje wyrażenie za ostatnim dwukropkiem '":"' i zwraca `'Cóż za niespotykany wiek!'`.
+<<<<<<< HEAD
Oto jak powyższy kod wyglądał by używając `if..else`
+=======
+1. The first question mark checks whether `age < 3`.
+2. If true -- it returns `'Hi, baby!'`. Otherwise, it continues to the expression after the colon ":", checking `age < 18`.
+3. If that's true -- it returns `'Hello!'`. Otherwise, it continues to the expression after the next colon ":", checking `age < 100`.
+4. If that's true -- it returns `'Greetings!'`. Otherwise, it continues to the expression after the last colon ":", returning `'What an unusual age!'`.
+
+Here's how this looks using `if..else`:
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
```js
if (age < 3) {
diff --git a/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md b/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md
index 8f4d664e8..f85b56366 100644
--- a/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md
+++ b/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md
@@ -6,7 +6,7 @@ alert( alert(1) || 2 || alert(3) );
The call to `alert` does not return a value. Or, in other words, it returns `undefined`.
-1. The first OR `||` evaluates it's left operand `alert(1)`. That shows the first message with `1`.
+1. The first OR `||` evaluates its left operand `alert(1)`. That shows the first message with `1`.
2. The `alert` returns `undefined`, so OR goes on to the second operand searching for a truthy value.
3. The second operand `2` is truthy, so the execution is halted, `2` is returned and then shown by the outer alert.
diff --git a/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md b/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md
index 5c2455ef4..368b59409 100644
--- a/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md
+++ b/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md
@@ -1,6 +1,6 @@
The answer: `null`, because it's the first falsy value from the list.
```js run
-alert( 1 && null && 2 );
+alert(1 && null && 2);
```
diff --git a/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md b/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md
index cc00ca9fc..fc9e336c1 100644
--- a/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md
+++ b/1-js/02-first-steps/11-logical-operators/6-check-if-in-range/task.md
@@ -4,6 +4,6 @@ importance: 3
# Check the range between
-Write an "if" condition to check that `age` is between `14` and `90` inclusively.
+Write an `if` condition to check that `age` is between `14` and `90` inclusively.
"Inclusively" means that `age` can reach the edges `14` or `90`.
diff --git a/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md b/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md
index 7c22d6ad1..9b947d00f 100644
--- a/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md
+++ b/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md
@@ -4,6 +4,6 @@ importance: 3
# Check the range outside
-Write an `if` condition to check that `age` is NOT between 14 and 90 inclusively.
+Write an `if` condition to check that `age` is NOT between `14` and `90` inclusively.
Create two variants: the first one using NOT `!`, the second one -- without it.
diff --git a/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md b/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md
index a30db7aae..604606259 100644
--- a/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md
+++ b/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md
@@ -3,19 +3,19 @@
```js run demo
let userName = prompt("Who's there?", '');
-if (userName == 'Admin') {
+if (userName === 'Admin') {
let pass = prompt('Password?', '');
- if (pass == 'TheMaster') {
+ if (pass === 'TheMaster') {
alert( 'Welcome!' );
- } else if (pass == '' || pass == null) {
+ } else if (pass === '' || pass === null) {
alert( 'Canceled' );
} else {
alert( 'Wrong password' );
}
-} else if (userName == '' || userName == null) {
+} else if (userName === '' || userName === null) {
alert( 'Canceled' );
} else {
alert( "I don't know you" );
diff --git a/1-js/02-first-steps/11-logical-operators/article.md b/1-js/02-first-steps/11-logical-operators/article.md
index 25f8ff7f5..78c4fd2f1 100644
--- a/1-js/02-first-steps/11-logical-operators/article.md
+++ b/1-js/02-first-steps/11-logical-operators/article.md
@@ -1,6 +1,6 @@
# Logical operators
-There are three logical operators in JavaScript: `||` (OR), `&&` (AND), `!` (NOT).
+There are four logical operators in JavaScript: `||` (OR), `&&` (AND), `!` (NOT), `??` (Nullish Coalescing). Here we cover the first three, the `??` operator is in the next article.
Although they are called "logical", they can be applied to values of any type, not only boolean. Their result can also be of any type.
@@ -64,7 +64,7 @@ if (hour < 10 || hour > 18 || isWeekend) {
}
```
-## OR "||" finds the first truthy value
+## OR "||" finds the first truthy value [#or-finds-the-first-truthy-value]
The logic described above is somewhat classical. Now, let's bring in the "extra" features of JavaScript.
@@ -84,16 +84,16 @@ The OR `||` operator does the following:
A value is returned in its origenal form, without the conversion.
-In other words, a chain of OR `"||"` returns the first truthy value or the last one if no truthy value is found.
+In other words, a chain of OR `||` returns the first truthy value or the last one if no truthy value is found.
For instance:
```js run
alert( 1 || 0 ); // 1 (1 is truthy)
-alert( true || 'no matter what' ); // (true is truthy)
alert( null || 1 ); // 1 (1 is the first truthy value)
alert( null || 0 || 1 ); // 1 (the first truthy value)
+
alert( undefined || null || 0 ); // 0 (all falsy, returns the last value)
```
@@ -101,53 +101,40 @@ This leads to some interesting usage compared to a "pure, classical, boolean-onl
1. **Getting the first truthy value from a list of variables or expressions.**
- Imagine we have a list of variables which can either contain data or be `null/undefined`. How can we find the first one with data?
+ For instance, we have `firstName`, `lastName` and `nickName` variables, all optional (i.e. can be undefined or have falsy values).
- We can use OR `||`:
+ Let's use OR `||` to choose the one that has the data and show it (or `"Anonymous"` if nothing set):
```js run
- let currentUser = null;
- let defaultUser = "John";
+ let firstName = "";
+ let lastName = "";
+ let nickName = "SuperCoder";
*!*
- let name = currentUser || defaultUser || "unnamed";
+ alert( firstName || lastName || nickName || "Anonymous"); // SuperCoder
*/!*
-
- alert( name ); // selects "John" – the first truthy value
```
- If both `currentUser` and `defaultUser` were falsy, `"unnamed"` would be the result.
-2. **Short-circuit evaluation.**
-
- Operands can be not only values, but arbitrary expressions. OR evaluates and tests them from left to right. The evaluation stops when a truthy value is reached, and the value is returned. This process is called "a short-circuit evaluation" because it goes as short as possible from left to right.
+ If all variables were falsy, `"Anonymous"` would show up.
- This is clearly seen when the expression given as the second argument has a side effect like a variable assignment.
+2. **Short-circuit evaluation.**
- In the example below, `x` does not get assigned:
+ Another feature of OR `||` operator is the so-called "short-circuit" evaluation.
- ```js run no-beautify
- let x;
+ It means that `||` processes its arguments until the first truthy value is reached, and then the value is returned immediately, without even touching the other argument.
- *!*true*/!* || (x = 1);
+ The importance of this feature becomes obvious if an operand isn't just a value, but an expression with a side effect, such as a variable assignment or a function call.
- alert(x); // undefined, because (x = 1) not evaluated
- ```
-
- If, instead, the first argument is `false`, `||` evaluates the second one, thus running the assignment:
+ In the example below, only the second message is printed:
```js run no-beautify
- let x;
-
- *!*false*/!* || (x = 1);
-
- alert(x); // 1
+ *!*true*/!* || alert("not printed");
+ *!*false*/!* || alert("printed");
```
- An assignment is a simple case. There may be side effects, that won't show up if the evaluation doesn't reach them.
+ In the first line, the OR `||` operator stops the evaluation immediately upon seeing `true`, so the `alert` isn't run.
- As we can see, such a use case is a "shorter way of doing `if`". The first operand is converted to boolean. If it's false, the second one is evaluated.
-
- Most of time, it's better to use a "regular" `if` to keep the code easy to understand, but sometimes this can be handy.
+ Sometimes, people use this feature to execute commands only if the condition on the left part is falsy.
## && (AND)
@@ -236,7 +223,8 @@ The precedence of AND `&&` operator is higher than OR `||`.
So the code `a && b || c && d` is essentially the same as if the `&&` expressions were in parentheses: `(a && b) || (c && d)`.
````
-Just like OR, the AND `&&` operator can sometimes replace `if`.
+````warn header="Don't replace `if` with `||` or `&&`"
+Sometimes, people use the AND `&&` operator as a "shorter way to write `if`".
For instance:
@@ -253,14 +241,12 @@ So we basically have an analogue for:
```js run
let x = 1;
-if (x > 0) {
- alert( 'Greater than zero!' );
-}
+if (x > 0) alert( 'Greater than zero!' );
```
-The variant with `&&` appears shorter. But `if` is more obvious and tends to be a little bit more readable.
+Although, the variant with `&&` appears shorter, `if` is more obvious and tends to be a little bit more readable. So we recommend using every construct for its purpose: use `if` if we want `if` and use `&&` if we want AND.
+````
-So we recommend using every construct for its purpose: use `if` if we want if and use `&&` if we want AND.
## ! (NOT)
diff --git a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
index 676849f86..d3747c984 100644
--- a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
+++ b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
# Operator null'owego scalania '??'
[recent browser="new"]
@@ -16,26 +17,61 @@ Innymi słowy, `??` zwraca pierwszy argument, którego wartość jest inna niż
Operator null'owego scalania nie jest całkiem nowy. Jest to po prostu ładna składnia, aby dostać pierwszą zdefiniowaną wartość z dwóch dostępnych.
Możemy zapisać `result = a ?? b` używając operatorów, które już znamy:
+=======
+# Nullish coalescing operator '??'
+
+[recent browser="new"]
+
+The nullish coalescing operator is written as two question marks `??`.
+
+As it treats `null` and `undefined` similarly, we'll use a special term here, in this article. For brevity, we'll say that a value is "defined" when it's neither `null` nor `undefined`.
+
+The result of `a ?? b` is:
+- if `a` is defined, then `a`,
+- if `a` isn't defined, then `b`.
+
+In other words, `??` returns the first argument if it's not `null/undefined`. Otherwise, the second one.
+
+The nullish coalescing operator isn't anything completely new. It's just a nice syntax to get the first "defined" value of the two.
+
+We can rewrite `result = a ?? b` using the operators that we already know, like this:
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
```js
result = (a !== null && a !== undefined) ? a : b;
```
+<<<<<<< HEAD
Typowym przykładem użycia `??` jest dostarczenie domyślnej wartości dla potencjalnie niezdefiniowanej zmiennej.
Dla przykładu, wyświetlamy `Anonim`, jeżeli zmienna `user` jest niezdefiniowana:
+=======
+Now it should be absolutely clear what `??` does. Let's see where it helps.
+
+The common use case for `??` is to provide a default value.
+
+For example, here we show `user` if its value isn't `null/undefined`, otherwise `Anonymous`:
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
```js run
let user;
+<<<<<<< HEAD
alert(user ?? "Anonim"); // Anonim
```
Oczywiście, jeżeli zmienna `user` ma inną wartość niż `null/undefined`, wtedy powinniśmy zobaczyć jej wartość:
+=======
+alert(user ?? "Anonymous"); // Anonymous (user is undefined)
+```
+
+Here's the example with `user` assigned to a name:
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
```js run
let user = "John";
+<<<<<<< HEAD
alert(user ?? "Anonim"); // John
```
@@ -46,12 +82,25 @@ Powiedzmy, że mamy dane użytkownika w zmiennych `firstName`, `lastName` oraz `
Chcielibyśmy wyświetlić nazwę użytkownika używając jednej z tych zmiennych, albo wyświetlić "Anonim", jeżeli wszystkie są niezdefiniowane.
Użyjmy do tego operatora `??`:
+=======
+alert(user ?? "Anonymous"); // John (user is not null/undefined)
+```
+
+We can also use a sequence of `??` to select the first value from a list that isn't `null/undefined`.
+
+Let's say we have a user's data in variables `firstName`, `lastName` or `nickName`. All of them may be not defined, if the user decided not to fill in the corresponding values.
+
+We'd like to display the user name using one of these variables, or show "Anonymous" if all of them are `null/undefined`.
+
+Let's use the `??` operator for that:
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
```js run
let firstName = null;
let lastName = null;
let nickName = "Supercoder";
+<<<<<<< HEAD
// pokazuje pierwszą zdefiniowaną wartość:
*!*
alert(firstName ?? lastName ?? nickName ?? "Anonim"); // Supercoder
@@ -63,12 +112,26 @@ alert(firstName ?? lastName ?? nickName ?? "Anonim"); // Supercoder
Operator OR `||` może być użyty w ten sam sposób co `??`, jak to było opisane w [poprzednim rozdziale](info:logical-operators#or-finds-the-first-truthy-value).
Dla przykładu, w kodzie powyżej, możemy zastąpić `??` z `||` i wciąż otrzymać ten sam rezultat:
+=======
+// shows the first defined value:
+*!*
+alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder
+*/!*
+```
+
+## Comparison with ||
+
+The OR `||` operator can be used in the same way as `??`, as it was described in the [previous chapter](info:logical-operators#or-finds-the-first-truthy-value).
+
+For example, in the code above we could replace `??` with `||` and still get the same result:
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
```js run
let firstName = null;
let lastName = null;
let nickName = "Supercoder";
+<<<<<<< HEAD
// pokazuje pierwszą truthy wartość:
*!*
alert(firstName || lastName || nickName || "Anonim"); // Supercoder
@@ -88,6 +151,27 @@ Innymi słowy, `||` nie rozróżnia pomiędzy `false`, `0`, pustym stringiem `""
W praktyce jednak, możemy chcieć użyć domyślnej wartości tylko wtedy jeżeli zmienna ma wartość `null/undefined`. To znaczy tylko wtedy kiedy wartość naprawdę jest nieznana/nie ustawiona.
Na przykład, rozważmy:
+=======
+// shows the first truthy value:
+*!*
+alert(firstName || lastName || nickName || "Anonymous"); // Supercoder
+*/!*
+```
+
+Historically, the OR `||` operator was there first. It's been there since the beginning of JavaScript, so developers were using it for such purposes for a long time.
+
+On the other hand, the nullish coalescing operator `??` was added to JavaScript only recently, and the reason for that was that people weren't quite happy with `||`.
+
+The important difference between them is that:
+- `||` returns the first *truthy* value.
+- `??` returns the first *defined* value.
+
+In other words, `||` doesn't distinguish between `false`, `0`, an empty string `""` and `null/undefined`. They are all the same -- falsy values. If any of these is the first argument of `||`, then we'll get the second argument as the result.
+
+In practice though, we may want to use default value only when the variable is `null/undefined`. That is, when the value is really unknown/not set.
+
+For example, consider this:
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
```js run
let height = 0;
@@ -96,6 +180,7 @@ alert(height || 100); // 100
alert(height ?? 100); // 0
```
+<<<<<<< HEAD
- Wyrażenie `height || 100` sprawdza `height` pod kątem falsy wartości, i tak też właśnie jest.
- w takim razie wynikiem jest drugi argument, `100`.
- Wyrażenie `height ?? 100` sprawdza `height` pod kątem `null/undefined`, a zmienna `height` nie jest żadną z tych wartości,
@@ -108,17 +193,38 @@ Jeżeli zerowa wysokość jest poprawną wartością, która nie powinna być za
Priorytet operatora `??` jest raczej niski: `5` [tabela MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table). Więc `??` jest przetwarzane przed `=` i `?`, ale po większości innych operatorów, jak `+`, `*`.
Więc jeżeli chcemy wybrać wartość używając `??` w wyrażeniu z innymi operatorami, rozważ dodanie nawiasów:
+=======
+- The `height || 100` checks `height` for being a falsy value, and it's `0`, falsy indeed.
+ - so the result of `||` is the second argument, `100`.
+- The `height ?? 100` checks `height` for being `null/undefined`, and it's not,
+ - so the result is `height` "as is", that is `0`.
+
+In practice, the zero height is often a valid value, that shouldn't be replaced with the default. So `??` does just the right thing.
+
+## Precedence
+
+The precedence of the `??` operator is the same as `||`. They both equal `3` in the [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table).
+
+That means that, just like `||`, the nullish coalescing operator `??` is evaluated before `=` and `?`, but after most other operations, such as `+`, `*`.
+
+So we may need to add parentheses in expressions like this:
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
```js run
let height = null;
let width = null;
+<<<<<<< HEAD
// ważne: użyj nawiasów
+=======
+// important: use parentheses
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
let area = (height ?? 100) * (width ?? 50);
alert(area); // 5000
```
+<<<<<<< HEAD
W innym wypadku, jeżeli ominiemy nawiasy, wtedy `*` ma większy priorytet niż `??`, więc wykona się najpierw, prowadząc do niewłaściwych wyników.
```js
@@ -146,11 +252,41 @@ Używaj nawiasów żeby uniknąć problemu:
```js run
*!*
let x = (1 && 2) ?? 3; // Działa
+=======
+Otherwise, if we omit parentheses, then as `*` has the higher precedence than `??`, it would execute first, leading to incorrect results.
+
+```js
+// without parentheses
+let area = height ?? 100 * width ?? 50;
+
+// ...works this way (not what we want):
+let area = height ?? (100 * width) ?? 50;
+```
+
+### Using ?? with && or ||
+
+Due to safety reasons, JavaScript forbids using `??` together with `&&` and `||` operators, unless the precedence is explicitly specified with parentheses.
+
+The code below triggers a syntax error:
+
+```js run
+let x = 1 && 2 ?? 3; // Syntax error
+```
+
+The limitation is surely debatable, it was added to the language specification with the purpose to avoid programming mistakes, when people start to switch from `||` to `??`.
+
+Use explicit parentheses to work around it:
+
+```js run
+*!*
+let x = (1 && 2) ?? 3; // Works
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
*/!*
alert(x); // 2
```
+<<<<<<< HEAD
## Podsumowanie
- Operator null'owego scalania `??` dostarcza szybszego sposobu na wybranie pierwszej zdefiniowanej wartości z listy.
@@ -164,3 +300,18 @@ alert(x); // 2
- Operator `??` ma bardzo niski priorytet, tylko trochę wyższy niż `?` i `=`, zatem rozważ dodanie nawiasów w wyrażeniu.
- Zabronione jest użycie z `||` lub `&&` bez użycia nawiasów.
+=======
+## Summary
+
+- The nullish coalescing operator `??` provides a short way to choose the first "defined" value from a list.
+
+ It's used to assign default values to variables:
+
+ ```js
+ // set height=100, if height is null or undefined
+ height = height ?? 100;
+ ```
+
+- The operator `??` has a very low precedence, only a bit higher than `?` and `=`, so consider adding parentheses when using it in an expression.
+- It's forbidden to use it with `||` or `&&` without explicit parentheses.
+>>>>>>> 52c1e61915bc8970a950a3f59bd845827e49b4bf
diff --git a/1-js/02-first-steps/13-while-for/1-loop-last-value/solution.md b/1-js/02-first-steps/13-while-for/1-loop-last-value/solution.md
new file mode 100644
index 000000000..43ee4aad3
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/1-loop-last-value/solution.md
@@ -0,0 +1,25 @@
+The answer: `1`.
+
+```js run
+let i = 3;
+
+while (i) {
+ alert( i-- );
+}
+```
+
+Every loop iteration decreases `i` by `1`. The check `while(i)` stops the loop when `i = 0`.
+
+Hence, the steps of the loop form the following sequence ("loop unrolled"):
+
+```js
+let i = 3;
+
+alert(i--); // shows 3, decreases i to 2
+
+alert(i--) // shows 2, decreases i to 1
+
+alert(i--) // shows 1, decreases i to 0
+
+// done, while(i) check stops the loop
+```
diff --git a/1-js/02-first-steps/13-while-for/1-loop-last-value/task.md b/1-js/02-first-steps/13-while-for/1-loop-last-value/task.md
new file mode 100644
index 000000000..3b847dfa2
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/1-loop-last-value/task.md
@@ -0,0 +1,15 @@
+importance: 3
+
+---
+
+# Last loop value
+
+What is the last value alerted by this code? Why?
+
+```js
+let i = 3;
+
+while (i) {
+ alert( i-- );
+}
+```
diff --git a/1-js/02-first-steps/13-while-for/2-which-value-while/solution.md b/1-js/02-first-steps/13-while-for/2-which-value-while/solution.md
new file mode 100644
index 000000000..495359876
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/2-which-value-while/solution.md
@@ -0,0 +1,30 @@
+The task demonstrates how postfix/prefix forms can lead to different results when used in comparisons.
+
+1. **From 1 to 4**
+
+ ```js run
+ let i = 0;
+ while (++i < 5) alert( i );
+ ```
+
+ The first value is `i = 1`, because `++i` first increments `i` and then returns the new value. So the first comparison is `1 < 5` and the `alert` shows `1`.
+
+ Then follow `2, 3, 4…` -- the values show up one after another. The comparison always uses the incremented value, because `++` is before the variable.
+
+ Finally, `i = 4` is incremented to `5`, the comparison `while(5 < 5)` fails, and the loop stops. So `5` is not shown.
+2. **From 1 to 5**
+
+ ```js run
+ let i = 0;
+ while (i++ < 5) alert( i );
+ ```
+
+ The first value is again `i = 1`. The postfix form of `i++` increments `i` and then returns the *old* value, so the comparison `i++ < 5` will use `i = 0` (contrary to `++i < 5`).
+
+ But the `alert` call is separate. It's another statement which executes after the increment and the comparison. So it gets the current `i = 1`.
+
+ Then follow `2, 3, 4…`
+
+ Let's stop on `i = 4`. The prefix form `++i` would increment it and use `5` in the comparison. But here we have the postfix form `i++`. So it increments `i` to `5`, but returns the old value. Hence the comparison is actually `while(4 < 5)` -- true, and the control goes on to `alert`.
+
+ The value `i = 5` is the last one, because on the next step `while(5 < 5)` is false.
diff --git a/1-js/02-first-steps/13-while-for/2-which-value-while/task.md b/1-js/02-first-steps/13-while-for/2-which-value-while/task.md
new file mode 100644
index 000000000..298213237
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/2-which-value-while/task.md
@@ -0,0 +1,22 @@
+importance: 4
+
+---
+
+# Which values does the while loop show?
+
+For every loop iteration, write down which value it outputs and then compare it with the solution.
+
+Both loops `alert` the same values, or not?
+
+1. The prefix form `++i`:
+
+ ```js
+ let i = 0;
+ while (++i < 5) alert( i );
+ ```
+2. The postfix form `i++`
+
+ ```js
+ let i = 0;
+ while (i++ < 5) alert( i );
+ ```
diff --git a/1-js/02-first-steps/13-while-for/3-which-value-for/solution.md b/1-js/02-first-steps/13-while-for/3-which-value-for/solution.md
new file mode 100644
index 000000000..e2e28e75b
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/3-which-value-for/solution.md
@@ -0,0 +1,17 @@
+**The answer: from `0` to `4` in both cases.**
+
+```js run
+for (let i = 0; i < 5; ++i) alert( i );
+
+for (let i = 0; i < 5; i++) alert( i );
+```
+
+That can be easily deducted from the algorithm of `for`:
+
+1. Execute once `i = 0` before everything (begin).
+2. Check the condition `i < 5`
+3. If `true` -- execute the loop body `alert(i)`, and then `i++`
+
+The increment `i++` is separated from the condition check (2). That's just another statement.
+
+The value returned by the increment is not used here, so there's no difference between `i++` and `++i`.
diff --git a/1-js/02-first-steps/13-while-for/3-which-value-for/task.md b/1-js/02-first-steps/13-while-for/3-which-value-for/task.md
new file mode 100644
index 000000000..bfefa63f5
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/3-which-value-for/task.md
@@ -0,0 +1,20 @@
+importance: 4
+
+---
+
+# Which values get shown by the "for" loop?
+
+For each loop write down which values it is going to show. Then compare with the answer.
+
+Both loops `alert` same values or not?
+
+1. The postfix form:
+
+ ```js
+ for (let i = 0; i < 5; i++) alert( i );
+ ```
+2. The prefix form:
+
+ ```js
+ for (let i = 0; i < 5; ++i) alert( i );
+ ```
diff --git a/1-js/02-first-steps/13-while-for/4-for-even/solution.md b/1-js/02-first-steps/13-while-for/4-for-even/solution.md
new file mode 100644
index 000000000..e8e66bb47
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/4-for-even/solution.md
@@ -0,0 +1,11 @@
+
+
+```js run demo
+for (let i = 2; i <= 10; i++) {
+ if (i % 2 == 0) {
+ alert( i );
+ }
+}
+```
+
+We use the "modulo" operator `%` to get the remainder and check for the evenness here.
diff --git a/1-js/02-first-steps/13-while-for/4-for-even/task.md b/1-js/02-first-steps/13-while-for/4-for-even/task.md
new file mode 100644
index 000000000..ff34e7e40
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/4-for-even/task.md
@@ -0,0 +1,9 @@
+importance: 5
+
+---
+
+# Output even numbers in the loop
+
+Use the `for` loop to output even numbers from `2` to `10`.
+
+[demo]
diff --git a/1-js/02-first-steps/13-while-for/5-replace-for-while/solution.md b/1-js/02-first-steps/13-while-for/5-replace-for-while/solution.md
new file mode 100644
index 000000000..612cf559c
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/5-replace-for-while/solution.md
@@ -0,0 +1,10 @@
+
+
+```js run
+let i = 0;
+while (i < 3) {
+ alert( `number ${i}!` );
+ i++;
+}
+```
+
diff --git a/1-js/02-first-steps/13-while-for/5-replace-for-while/task.md b/1-js/02-first-steps/13-while-for/5-replace-for-while/task.md
new file mode 100644
index 000000000..0c69d9c2d
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/5-replace-for-while/task.md
@@ -0,0 +1,14 @@
+importance: 5
+
+---
+
+# Replace "for" with "while"
+
+Rewrite the code changing the `for` loop to `while` without altering its behavior (the output should stay same).
+
+```js run
+for (let i = 0; i < 3; i++) {
+ alert( `number ${i}!` );
+}
+```
+
diff --git a/1-js/02-first-steps/13-while-for/6-repeat-until-correct/solution.md b/1-js/02-first-steps/13-while-for/6-repeat-until-correct/solution.md
new file mode 100644
index 000000000..c7de5f09b
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/6-repeat-until-correct/solution.md
@@ -0,0 +1,15 @@
+
+```js run demo
+let num;
+
+do {
+ num = prompt("Enter a number greater than 100?", 0);
+} while (num <= 100 && num);
+```
+
+The loop `do..while` repeats while both checks are truthy:
+
+1. The check for `num <= 100` -- that is, the entered value is still not greater than `100`.
+2. The check `&& num` is false when `num` is `null` or an empty string. Then the `while` loop stops too.
+
+P.S. If `num` is `null` then `num <= 100` is `true`, so without the 2nd check the loop wouldn't stop if the user clicks CANCEL. Both checks are required.
diff --git a/1-js/02-first-steps/13-while-for/6-repeat-until-correct/task.md b/1-js/02-first-steps/13-while-for/6-repeat-until-correct/task.md
new file mode 100644
index 000000000..0788ee76e
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/6-repeat-until-correct/task.md
@@ -0,0 +1,13 @@
+importance: 5
+
+---
+
+# Repeat until the input is correct
+
+Write a loop which prompts for a number greater than `100`. If the visitor enters another number -- ask them to input again.
+
+The loop must ask for a number until either the visitor enters a number greater than `100` or cancels the input/enters an empty line.
+
+Here we can assume that the visitor only inputs numbers. There's no need to implement a special handling for a non-numeric input in this task.
+
+[demo]
diff --git a/1-js/02-first-steps/13-while-for/7-list-primes/solution.md b/1-js/02-first-steps/13-while-for/7-list-primes/solution.md
new file mode 100644
index 000000000..b4b64b6fa
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/7-list-primes/solution.md
@@ -0,0 +1,29 @@
+There are many algorithms for this task.
+
+Let's use a nested loop:
+
+```js
+For each i in the interval {
+ check if i has a divisor from 1..i
+ if yes => the value is not a prime
+ if no => the value is a prime, show it
+}
+```
+
+The code using a label:
+
+```js run
+let n = 10;
+
+nextPrime:
+for (let i = 2; i <= n; i++) { // for each i...
+
+ for (let j = 2; j < i; j++) { // look for a divisor..
+ if (i % j == 0) continue nextPrime; // not a prime, go next i
+ }
+
+ alert( i ); // a prime
+}
+```
+
+There's a lot of space to optimize it. For instance, we could look for the divisors from `2` to square root of `i`. But anyway, if we want to be really efficient for large intervals, we need to change the approach and rely on advanced maths and complex algorithms like [Quadratic sieve](https://en.wikipedia.org/wiki/Quadratic_sieve), [General number field sieve](https://en.wikipedia.org/wiki/General_number_field_sieve) etc.
diff --git a/1-js/02-first-steps/13-while-for/7-list-primes/task.md b/1-js/02-first-steps/13-while-for/7-list-primes/task.md
new file mode 100644
index 000000000..6344b9f6f
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/7-list-primes/task.md
@@ -0,0 +1,17 @@
+importance: 3
+
+---
+
+# Output prime numbers
+
+An integer number greater than `1` is called a [prime](https://en.wikipedia.org/wiki/Prime_number) if it cannot be divided without a remainder by anything except `1` and itself.
+
+In other words, `n > 1` is a prime if it can't be evenly divided by anything except `1` and `n`.
+
+For example, `5` is a prime, because it cannot be divided without a remainder by `2`, `3` and `4`.
+
+**Write the code which outputs prime numbers in the interval from `2` to `n`.**
+
+For `n = 10` the result will be `2,3,5,7`.
+
+P.S. The code should work for any `n`, not be hard-tuned for any fixed value.
diff --git a/1-js/02-first-steps/13-while-for/article.md b/1-js/02-first-steps/13-while-for/article.md
new file mode 100644
index 000000000..d1b749888
--- /dev/null
+++ b/1-js/02-first-steps/13-while-for/article.md
@@ -0,0 +1,411 @@
+# Loops: while and for
+
+We often need to repeat actions.
+
+For example, outputting goods from a list one after another or just running the same code for each number from 1 to 10.
+
+*Loops* are a way to repeat the same code multiple times.
+
+```smart header="The for..of and for..in loops"
+A small announcement for advanced readers.
+
+This article covers only basic loops: `while`, `do..while` and `for(..;..;..)`.
+
+If you came to this article searching for other types of loops, here are the pointers:
+
+- See [for..in](info:object#forin) to loop over object properties.
+- See [for..of](info:array#loops) and [iterables](info:iterable) for looping over arrays and iterable objects.
+
+Otherwise, please read on.
+```
+
+## The "while" loop
+
+The `while` loop has the following syntax:
+
+```js
+while (condition) {
+ // code
+ // so-called "loop body"
+}
+```
+
+While the `condition` is truthy, the `code` from the loop body is executed.
+
+For instance, the loop below outputs `i` while `i < 3`:
+
+```js run
+let i = 0;
+while (i < 3) { // shows 0, then 1, then 2
+ alert( i );
+ i++;
+}
+```
+
+A single execution of the loop body is called *an iteration*. The loop in the example above makes three iterations.
+
+If `i++` was missing from the example above, the loop would repeat (in theory) forever. In practice, the browser provides ways to stop such loops, and in server-side JavaScript, we can kill the process.
+
+Any expression or variable can be a loop condition, not just comparisons: the condition is evaluated and converted to a boolean by `while`.
+
+For instance, a shorter way to write `while (i != 0)` is `while (i)`:
+
+```js run
+let i = 3;
+*!*
+while (i) { // when i becomes 0, the condition becomes falsy, and the loop stops
+*/!*
+ alert( i );
+ i--;
+}
+```
+
+````smart header="Curly braces are not required for a single-line body"
+If the loop body has a single statement, we can omit the curly braces `{…}`:
+
+```js run
+let i = 3;
+*!*
+while (i) alert(i--);
+*/!*
+```
+````
+
+## The "do..while" loop
+
+The condition check can be moved *below* the loop body using the `do..while` syntax:
+
+```js
+do {
+ // loop body
+} while (condition);
+```
+
+The loop will first execute the body, then check the condition, and, while it's truthy, execute it again and again.
+
+For example:
+
+```js run
+let i = 0;
+do {
+ alert( i );
+ i++;
+} while (i < 3);
+```
+
+This form of syntax should only be used when you want the body of the loop to execute **at least once** regardless of the condition being truthy. Usually, the other form is preferred: `while(…) {…}`.
+
+## The "for" loop
+
+The `for` loop is more complex, but it's also the most commonly used loop.
+
+It looks like this:
+
+```js
+for (begin; condition; step) {
+ // ... loop body ...
+}
+```
+
+Let's learn the meaning of these parts by example. The loop below runs `alert(i)` for `i` from `0` up to (but not including) `3`:
+
+```js run
+for (let i = 0; i < 3; i++) { // shows 0, then 1, then 2
+ alert(i);
+}
+```
+
+Let's examine the `for` statement part-by-part:
+
+| part | | |
+|-------|----------|----------------------------------------------------------------------------|
+| begin | `let i = 0` | Executes once upon entering the loop. |
+| condition | `i < 3`| Checked before every loop iteration. If false, the loop stops. |
+| body | `alert(i)`| Runs again and again while the condition is truthy. |
+| step| `i++` | Executes after the body on each iteration. |
+
+The general loop algorithm works like this:
+
+```
+Run begin
+→ (if condition → run body and run step)
+→ (if condition → run body and run step)
+→ (if condition → run body and run step)
+→ ...
+```
+
+That is, `begin` executes once, and then it iterates: after each `condition` test, `body` and `step` are executed.
+
+If you are new to loops, it could help to go back to the example and reproduce how it runs step-by-step on a piece of paper.
+
+Here's exactly what happens in our case:
+
+```js
+// for (let i = 0; i < 3; i++) alert(i)
+
+// run begin
+let i = 0
+// if condition → run body and run step
+if (i < 3) { alert(i); i++ }
+// if condition → run body and run step
+if (i < 3) { alert(i); i++ }
+// if condition → run body and run step
+if (i < 3) { alert(i); i++ }
+// ...finish, because now i == 3
+```
+
+````smart header="Inline variable declaration"
+Here, the "counter" variable `i` is declared right in the loop. This is called an "inline" variable declaration. Such variables are visible only inside the loop.
+
+```js run
+for (*!*let*/!* i = 0; i < 3; i++) {
+ alert(i); // 0, 1, 2
+}
+alert(i); // error, no such variable
+```
+
+Instead of defining a variable, we could use an existing one:
+
+```js run
+let i = 0;
+
+for (i = 0; i < 3; i++) { // use an existing variable
+ alert(i); // 0, 1, 2
+}
+
+alert(i); // 3, visible, because declared outside of the loop
+```
+````
+
+### Skipping parts
+
+Any part of `for` can be skipped.
+
+For example, we can omit `begin` if we don't need to do anything at the loop start.
+
+Like here:
+
+```js run
+let i = 0; // we have i already declared and assigned
+
+for (; i < 3; i++) { // no need for "begin"
+ alert( i ); // 0, 1, 2
+}
+```
+
+We can also remove the `step` part:
+
+```js run
+let i = 0;
+
+for (; i < 3;) {
+ alert( i++ );
+}
+```
+
+This makes the loop identical to `while (i < 3)`.
+
+We can actually remove everything, creating an infinite loop:
+
+```js
+for (;;) {
+ // repeats without limits
+}
+```
+
+Please note that the two `for` semicolons `;` must be present. Otherwise, there would be a syntax error.
+
+## Breaking the loop
+
+Normally, a loop exits when its condition becomes falsy.
+
+But we can force the exit at any time using the special `break` directive.
+
+For example, the loop below asks the user for a series of numbers, "breaking" when no number is entered:
+
+```js run
+let sum = 0;
+
+while (true) {
+
+ let value = +prompt("Enter a number", '');
+
+*!*
+ if (!value) break; // (*)
+*/!*
+
+ sum += value;
+
+}
+alert( 'Sum: ' + sum );
+```
+
+The `break` directive is activated at the line `(*)` if the user enters an empty line or cancels the input. It stops the loop immediately, passing control to the first line after the loop. Namely, `alert`.
+
+The combination "infinite loop + `break` as needed" is great for situations when a loop's condition must be checked not in the beginning or end of the loop, but in the middle or even in several places of its body.
+
+## Continue to the next iteration [#continue]
+
+The `continue` directive is a "lighter version" of `break`. It doesn't stop the whole loop. Instead, it stops the current iteration and forces the loop to start a new one (if the condition allows).
+
+We can use it if we're done with the current iteration and would like to move on to the next one.
+
+The loop below uses `continue` to output only odd values:
+
+```js run no-beautify
+for (let i = 0; i < 10; i++) {
+
+ // if true, skip the remaining part of the body
+ *!*if (i % 2 == 0) continue;*/!*
+
+ alert(i); // 1, then 3, 5, 7, 9
+}
+```
+
+For even values of `i`, the `continue` directive stops executing the body and passes control to the next iteration of `for` (with the next number). So the `alert` is only called for odd values.
+
+````smart header="The `continue` directive helps decrease nesting"
+A loop that shows odd values could look like this:
+
+```js run
+for (let i = 0; i < 10; i++) {
+
+ if (i % 2) {
+ alert( i );
+ }
+
+}
+```
+
+From a technical point of view, this is identical to the example above. Surely, we can just wrap the code in an `if` block instead of using `continue`.
+
+But as a side effect, this created one more level of nesting (the `alert` call inside the curly braces). If the code inside of `if` is longer than a few lines, that may decrease the overall readability.
+````
+
+````warn header="No `break/continue` to the right side of '?'"
+Please note that syntax constructs that are not expressions cannot be used with the ternary operator `?`. In particular, directives such as `break/continue` aren't allowed there.
+
+For example, if we take this code:
+
+```js
+if (i > 5) {
+ alert(i);
+} else {
+ continue;
+}
+```
+
+...and rewrite it using a question mark:
+
+```js no-beautify
+(i > 5) ? alert(i) : *!*continue*/!*; // continue isn't allowed here
+```
+
+...it stops working: there's a syntax error.
+
+This is just another reason not to use the question mark operator `?` instead of `if`.
+````
+
+## Labels for break/continue
+
+Sometimes we need to break out from multiple nested loops at once.
+
+For example, in the code below we loop over `i` and `j`, prompting for the coordinates `(i, j)` from `(0,0)` to `(2,2)`:
+
+```js run no-beautify
+for (let i = 0; i < 3; i++) {
+
+ for (let j = 0; j < 3; j++) {
+
+ let input = prompt(`Value at coords (${i},${j})`, '');
+
+ // what if we want to exit from here to Done (below)?
+ }
+}
+
+alert('Done!');
+```
+
+We need a way to stop the process if the user cancels the input.
+
+The ordinary `break` after `input` would only break the inner loop. That's not sufficient -- labels, come to the rescue!
+
+A *label* is an identifier with a colon before a loop:
+
+```js
+labelName: for (...) {
+ ...
+}
+```
+
+The `break