diff --git a/1-js/2-first-steps/11-uibasic/1-simple-page/solution.md b/1-js/2-first-steps/10-uibasic/1-simple-page/solution.md
similarity index 100%
rename from 1-js/2-first-steps/11-uibasic/1-simple-page/solution.md
rename to 1-js/2-first-steps/10-uibasic/1-simple-page/solution.md
diff --git a/1-js/2-first-steps/11-uibasic/1-simple-page/task.md b/1-js/2-first-steps/10-uibasic/1-simple-page/task.md
similarity index 100%
rename from 1-js/2-first-steps/11-uibasic/1-simple-page/task.md
rename to 1-js/2-first-steps/10-uibasic/1-simple-page/task.md
diff --git a/1-js/2-first-steps/11-uibasic/article.md b/1-js/2-first-steps/10-uibasic/article.md
similarity index 91%
rename from 1-js/2-first-steps/11-uibasic/article.md
rename to 1-js/2-first-steps/10-uibasic/article.md
index e1b00705..e83f9c87 100644
--- a/1-js/2-first-steps/11-uibasic/article.md
+++ b/1-js/2-first-steps/10-uibasic/article.md
@@ -92,9 +92,9 @@ alert(isAdmin);
## Особенности встроенных функций
-Место, где выводится модальное окно с вопросом, и внешний вид окна выбирает браузер. Разработчик не может на это влиять.
+Конкретное место, где выводится модальное окно с вопросом -- обычно это центр браузера, и внешний вид окна выбирает браузер. Разработчик не может на это влиять.
-С одной стороны -- это недостаток, т.к. нельзя вывести окно в своем дизайне.
+С одной стороны -- это недостаток, так как нельзя вывести окно в своем, особо красивом, дизайне.
С другой стороны, преимущество этих функций по сравнению с другими, более сложными методами взаимодействия, которые мы изучим в дальнейшем -- как раз в том, что они очень просты.
diff --git a/1-js/2-first-steps/12-ifelse/1-if-zero-string/solution.md b/1-js/2-first-steps/11-ifelse/1-if-zero-string/solution.md
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/1-if-zero-string/solution.md
rename to 1-js/2-first-steps/11-ifelse/1-if-zero-string/solution.md
diff --git a/1-js/2-first-steps/12-ifelse/1-if-zero-string/task.md b/1-js/2-first-steps/11-ifelse/1-if-zero-string/task.md
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/1-if-zero-string/task.md
rename to 1-js/2-first-steps/11-ifelse/1-if-zero-string/task.md
diff --git a/1-js/2-first-steps/12-ifelse/2-check-standard/ifelse_task2.png b/1-js/2-first-steps/11-ifelse/2-check-standard/ifelse_task2.png
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/2-check-standard/ifelse_task2.png
rename to 1-js/2-first-steps/11-ifelse/2-check-standard/ifelse_task2.png
diff --git a/1-js/2-first-steps/12-ifelse/2-check-standard/ifelse_task2/index.html b/1-js/2-first-steps/11-ifelse/2-check-standard/ifelse_task2/index.html
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/2-check-standard/ifelse_task2/index.html
rename to 1-js/2-first-steps/11-ifelse/2-check-standard/ifelse_task2/index.html
diff --git a/1-js/2-first-steps/12-ifelse/2-check-standard/solution.md b/1-js/2-first-steps/11-ifelse/2-check-standard/solution.md
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/2-check-standard/solution.md
rename to 1-js/2-first-steps/11-ifelse/2-check-standard/solution.md
diff --git a/1-js/2-first-steps/12-ifelse/2-check-standard/task.md b/1-js/2-first-steps/11-ifelse/2-check-standard/task.md
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/2-check-standard/task.md
rename to 1-js/2-first-steps/11-ifelse/2-check-standard/task.md
diff --git a/1-js/2-first-steps/12-ifelse/2-check-standardifelse_task2/index.html b/1-js/2-first-steps/11-ifelse/2-check-standardifelse_task2/index.html
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/2-check-standardifelse_task2/index.html
rename to 1-js/2-first-steps/11-ifelse/2-check-standardifelse_task2/index.html
diff --git a/1-js/2-first-steps/12-ifelse/3-sign/if_sign/index.html b/1-js/2-first-steps/11-ifelse/3-sign/if_sign/index.html
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/3-sign/if_sign/index.html
rename to 1-js/2-first-steps/11-ifelse/3-sign/if_sign/index.html
diff --git a/1-js/2-first-steps/12-ifelse/3-sign/solution.md b/1-js/2-first-steps/11-ifelse/3-sign/solution.md
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/3-sign/solution.md
rename to 1-js/2-first-steps/11-ifelse/3-sign/solution.md
diff --git a/1-js/2-first-steps/12-ifelse/3-sign/task.md b/1-js/2-first-steps/11-ifelse/3-sign/task.md
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/3-sign/task.md
rename to 1-js/2-first-steps/11-ifelse/3-sign/task.md
diff --git a/1-js/2-first-steps/12-ifelse/4-check-login/ifelse_task.png b/1-js/2-first-steps/11-ifelse/4-check-login/ifelse_task.png
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/4-check-login/ifelse_task.png
rename to 1-js/2-first-steps/11-ifelse/4-check-login/ifelse_task.png
diff --git a/1-js/2-first-steps/12-ifelse/4-check-login/solution.md b/1-js/2-first-steps/11-ifelse/4-check-login/solution.md
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/4-check-login/solution.md
rename to 1-js/2-first-steps/11-ifelse/4-check-login/solution.md
diff --git a/1-js/2-first-steps/12-ifelse/4-check-login/task.md b/1-js/2-first-steps/11-ifelse/4-check-login/task.md
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/4-check-login/task.md
rename to 1-js/2-first-steps/11-ifelse/4-check-login/task.md
diff --git a/1-js/2-first-steps/12-ifelse/5-rewrite-if-question/solution.md b/1-js/2-first-steps/11-ifelse/5-rewrite-if-question/solution.md
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/5-rewrite-if-question/solution.md
rename to 1-js/2-first-steps/11-ifelse/5-rewrite-if-question/solution.md
diff --git a/1-js/2-first-steps/12-ifelse/5-rewrite-if-question/task.md b/1-js/2-first-steps/11-ifelse/5-rewrite-if-question/task.md
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/5-rewrite-if-question/task.md
rename to 1-js/2-first-steps/11-ifelse/5-rewrite-if-question/task.md
diff --git a/1-js/2-first-steps/12-ifelse/6-rewrite-if-else-question/solution.md b/1-js/2-first-steps/11-ifelse/6-rewrite-if-else-question/solution.md
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/6-rewrite-if-else-question/solution.md
rename to 1-js/2-first-steps/11-ifelse/6-rewrite-if-else-question/solution.md
diff --git a/1-js/2-first-steps/12-ifelse/6-rewrite-if-else-question/task.md b/1-js/2-first-steps/11-ifelse/6-rewrite-if-else-question/task.md
similarity index 100%
rename from 1-js/2-first-steps/12-ifelse/6-rewrite-if-else-question/task.md
rename to 1-js/2-first-steps/11-ifelse/6-rewrite-if-else-question/task.md
diff --git a/1-js/2-first-steps/12-ifelse/article.md b/1-js/2-first-steps/11-ifelse/article.md
similarity index 68%
rename from 1-js/2-first-steps/12-ifelse/article.md
rename to 1-js/2-first-steps/11-ifelse/article.md
index 9547b6d1..9e9a9502 100644
--- a/1-js/2-first-steps/12-ifelse/article.md
+++ b/1-js/2-first-steps/11-ifelse/article.md
@@ -24,14 +24,20 @@ if (year != 2011) {
}
```
-**Рекомендуется использовать фигурные скобки всегда, даже когда команда одна.** Это улучшает читаемость кода.
+**Рекомендуется использовать фигурные скобки всегда, даже когда команда одна.**
+
+Это улучшает читаемость кода.
## Преобразование к логическому типу
Оператор `if (...)` вычисляет и преобразует выражение в скобках к логическому типу.
-**В логическом контексте число `0`, пустая строка `""`, `null` и `undefined`, а также `NaN` являются `false`, остальные значения -- `true`.**
+В логическом контексте:
+
+- Число `0`, пустая строка `""`, `null` и `undefined`, а также `NaN` являются `false`,
+- Остальные значения -- `true`.
+
Например, такое условие никогда не выполнится:
@@ -41,7 +47,7 @@ if (0) { // 0 преобразуется к false
}
```
-... А такое -- выполнится всегда:
+...А такое -- выполнится всегда:
```js
if (1) { // 1 преобразуется к true
@@ -49,7 +55,7 @@ if (1) { // 1 преобразуется к true
}
```
-Вычисление условия в проверке `if (year != 2011)` может быть вынесено в отдельную переменную:
+Можно и просто передать уже готовое логическое значение, к примеру, заранее вычисленное в переменной:
```js
var cond = (year != 2011); // true/false
@@ -65,7 +71,7 @@ if (cond) {
```js
//+ run
-var year = prompt('Введите год ECMA-262 5.1', '');
+var year = prompt('Введите год появления стандарта ECMA-262 5.1', '');
if (year == 2011) {
alert('Да вы знаток!');
@@ -121,7 +127,7 @@ alert(access);
условие ? значение1 : значение2
```
-Проверяется условие, затем если оно верно -- возвращается `значение1 `, если неверно -- `значение2`, например:
+Проверяется условие, затем если оно верно -- возвращается `значение1`, если неверно -- `значение2`, например:
```js
access = (age > 14) ? true : false;
@@ -141,7 +147,6 @@ access = age > 14 ? true : false;
```js
access = age > 14;
```
-
[/smart]
[smart header="\"Тернарный оператор\""]
@@ -152,39 +157,36 @@ access = age > 14;
## Несколько операторов '?'
-Несколько операторов `if..else` можно заменить последовательностью операторов `'?'`. Например:
+Последовательность операторов `'?'` позволяет вернуть значение в зависимости не от одного условия, а от нескольких.
+Например:
```js
//+ run
-var a = prompt('a?', 1);
+var age = prompt('возраст?', 18);
-*!*
-var res = (a == 1) ? 'значение1' :
- (a == 2) ? 'значение2' :
- (a > 2) ? 'значение3' :
- 'значение4';
-*/!*
+var message = (age < 3) ? 'Здравствуй, малыш!' :
+ (age < 18) ? 'Привет!' :
+ (age < 100) ? 'Здравствуйте!' :
+ 'Какой необычный возраст!';
-alert(res);
+alert(message);
```
-Поначалу может быть сложно понять, что происходит. Однако, внимательно приглядевшись, мы замечаем, что это *обычный `if..else`*!
+Поначалу может быть сложно понять, что происходит. Однако, внимательно приглядевшись, мы замечаем, что это обычная последовательная проверка!
-Вопросительный знак проверяет сначала `a == 1`, если верно -- возвращает `значение1`, если нет -- идет проверять `a == 2`. Если это верно -- возвращает `значение2`, иначе проверка `a > 2` и `значение3`... Наконец, если ничего не верно, то `значение4`.
+Вопросительный знак проверяет сначала `age < 3`, если верно -- возвращает `'Здравствуй, малыш!'`, если нет -- идет за двоеточие и проверяет `age < 18`. Если это верно -- возвращает `'Привет!'`, иначе проверка `age < 100` и `'Здравствуйте!'`... И наконец, если ничего из этого не верно, то `'Какой необычный возраст!'`.
-Альтернативный вариант с `if..else`:
+То же самое через `if..else`:
```js
-var res;
-
-if (a == 1) {
- res = 'значение1';
-} else if (a == 2) {
- res = 'значение2';
-} else if (a > 2) {
- res = 'значение3';
+if (age < 3) {
+ message = 'Здравствуй, малыш!';
+} else if (a < 18) {
+ message = 'Привет!';
+} else if (age < 100) {
+ message = 'Здравствуйте!';
} else {
- res = 'значение4';
+ message = 'Какой необычный возраст!';
}
```
@@ -225,3 +227,7 @@ if (company == 'Netscape') {
*/!*
```
+При чтении кода глаз идёт вертикально и конструкции, занимающие несколько строк, с понятной вложенностью, воспринимаются гораздо легче. Возможно, вы и сами почувствуете, пробежавшись глазами, что синтаксис с `if` более прост и очевиден чем с оператором `'?'`.
+
+Смысл оператора `'?'` -- вернуть то или иное значение, в зависимости от условия. Пожалуйста, используйте его по назначению, а для выполнения разных веток кода есть `if`.
+
diff --git a/1-js/2-first-steps/13-logical-ops/1-alert-null-2-undefined/solution.md b/1-js/2-first-steps/12-logical-ops/1-alert-null-2-undefined/solution.md
similarity index 100%
rename from 1-js/2-first-steps/13-logical-ops/1-alert-null-2-undefined/solution.md
rename to 1-js/2-first-steps/12-logical-ops/1-alert-null-2-undefined/solution.md
diff --git a/1-js/2-first-steps/13-logical-ops/1-alert-null-2-undefined/task.md b/1-js/2-first-steps/12-logical-ops/1-alert-null-2-undefined/task.md
similarity index 100%
rename from 1-js/2-first-steps/13-logical-ops/1-alert-null-2-undefined/task.md
rename to 1-js/2-first-steps/12-logical-ops/1-alert-null-2-undefined/task.md
diff --git a/1-js/2-first-steps/13-logical-ops/2-alert-or/solution.md b/1-js/2-first-steps/12-logical-ops/2-alert-or/solution.md
similarity index 100%
rename from 1-js/2-first-steps/13-logical-ops/2-alert-or/solution.md
rename to 1-js/2-first-steps/12-logical-ops/2-alert-or/solution.md
diff --git a/1-js/2-first-steps/13-logical-ops/2-alert-or/task.md b/1-js/2-first-steps/12-logical-ops/2-alert-or/task.md
similarity index 100%
rename from 1-js/2-first-steps/13-logical-ops/2-alert-or/task.md
rename to 1-js/2-first-steps/12-logical-ops/2-alert-or/task.md
diff --git a/1-js/2-first-steps/13-logical-ops/3-alert-1-null-2/solution.md b/1-js/2-first-steps/12-logical-ops/3-alert-1-null-2/solution.md
similarity index 100%
rename from 1-js/2-first-steps/13-logical-ops/3-alert-1-null-2/solution.md
rename to 1-js/2-first-steps/12-logical-ops/3-alert-1-null-2/solution.md
diff --git a/1-js/2-first-steps/13-logical-ops/3-alert-1-null-2/task.md b/1-js/2-first-steps/12-logical-ops/3-alert-1-null-2/task.md
similarity index 100%
rename from 1-js/2-first-steps/13-logical-ops/3-alert-1-null-2/task.md
rename to 1-js/2-first-steps/12-logical-ops/3-alert-1-null-2/task.md
diff --git a/1-js/2-first-steps/13-logical-ops/4-alert-and/solution.md b/1-js/2-first-steps/12-logical-ops/4-alert-and/solution.md
similarity index 100%
rename from 1-js/2-first-steps/13-logical-ops/4-alert-and/solution.md
rename to 1-js/2-first-steps/12-logical-ops/4-alert-and/solution.md
diff --git a/1-js/2-first-steps/13-logical-ops/4-alert-and/task.md b/1-js/2-first-steps/12-logical-ops/4-alert-and/task.md
similarity index 100%
rename from 1-js/2-first-steps/13-logical-ops/4-alert-and/task.md
rename to 1-js/2-first-steps/12-logical-ops/4-alert-and/task.md
diff --git a/1-js/2-first-steps/13-logical-ops/5-check-if-in-range/solution.md b/1-js/2-first-steps/12-logical-ops/5-check-if-in-range/solution.md
similarity index 100%
rename from 1-js/2-first-steps/13-logical-ops/5-check-if-in-range/solution.md
rename to 1-js/2-first-steps/12-logical-ops/5-check-if-in-range/solution.md
diff --git a/1-js/2-first-steps/13-logical-ops/5-check-if-in-range/task.md b/1-js/2-first-steps/12-logical-ops/5-check-if-in-range/task.md
similarity index 100%
rename from 1-js/2-first-steps/13-logical-ops/5-check-if-in-range/task.md
rename to 1-js/2-first-steps/12-logical-ops/5-check-if-in-range/task.md
diff --git a/1-js/2-first-steps/13-logical-ops/6-check-if-out-range/solution.md b/1-js/2-first-steps/12-logical-ops/6-check-if-out-range/solution.md
similarity index 100%
rename from 1-js/2-first-steps/13-logical-ops/6-check-if-out-range/solution.md
rename to 1-js/2-first-steps/12-logical-ops/6-check-if-out-range/solution.md
diff --git a/1-js/2-first-steps/13-logical-ops/6-check-if-out-range/task.md b/1-js/2-first-steps/12-logical-ops/6-check-if-out-range/task.md
similarity index 100%
rename from 1-js/2-first-steps/13-logical-ops/6-check-if-out-range/task.md
rename to 1-js/2-first-steps/12-logical-ops/6-check-if-out-range/task.md
diff --git a/1-js/2-first-steps/13-logical-ops/7-if-question/solution.md b/1-js/2-first-steps/12-logical-ops/7-if-question/solution.md
similarity index 100%
rename from 1-js/2-first-steps/13-logical-ops/7-if-question/solution.md
rename to 1-js/2-first-steps/12-logical-ops/7-if-question/solution.md
diff --git a/1-js/2-first-steps/13-logical-ops/7-if-question/task.md b/1-js/2-first-steps/12-logical-ops/7-if-question/task.md
similarity index 100%
rename from 1-js/2-first-steps/13-logical-ops/7-if-question/task.md
rename to 1-js/2-first-steps/12-logical-ops/7-if-question/task.md
diff --git a/1-js/2-first-steps/13-logical-ops/article.md b/1-js/2-first-steps/12-logical-ops/article.md
similarity index 73%
rename from 1-js/2-first-steps/13-logical-ops/article.md
rename to 1-js/2-first-steps/12-logical-ops/article.md
index 27742817..a132b6fb 100644
--- a/1-js/2-first-steps/13-logical-ops/article.md
+++ b/1-js/2-first-steps/12-logical-ops/article.md
@@ -1,8 +1,8 @@
# Логические операторы
-В JavaScript поддерживаются операторы `||` (ИЛИ), `&&` (И) и `!` (НЕ).
+Для операций над логическими значениями в JavaScript есть `||` (ИЛИ), `&&` (И) и `!` (НЕ).
-Они называются *"логическими"*, но в JavaScript могут применяться к значениям любого типа и возвращают также значения любого типа.
+Хоть они и называются *"логическими"*, но в JavaScript могут применяться к значениям любого типа и возвращают также значения любого типа.
[cut]
## || (ИЛИ)
@@ -15,7 +15,7 @@ result = a || b;
**Логическое ИЛИ в классическом программировании работает следующим образом: "если *хотя бы один* из аргументов `true`, то возвращает `true`, иначе -- `false`".**
-Получается следующая таблица результатов:
+Получается следующая "таблица результатов":
```js
//+ run
@@ -25,9 +25,7 @@ alert( true || false); // true
alert( false || false); // false
```
-При вычислении ИЛИ в JavaScript можно использовать любые значения. В этом случае они будут интерпретироваться как логические.
-
-Например, число `1` будет воспринято как `true`, а `0` -- как `false`:
+Если значение не логического типа -- то оно к нему приводится. Например, число `1` будет воспринято как `true`, а `0` -- как `false`:
```js
//+ run
@@ -86,6 +84,7 @@ alert(x); // undefined, x не присвоен
var x;
*!*false*/!* || (x = 1);
+
alert(x); // 1
```
@@ -93,9 +92,9 @@ alert(x); // 1
Итак, как мы видим, оператор ИЛИ вычисляет ровно столько значений, сколько необходимо -- до первого `true`.
-**Оператор ИЛИ возвращает то значение, на котором остановились вычисления.**
+При этом оператор ИЛИ возвращает то значение, на котором остановились вычисления. Причём, не преобразованное к логическому типу.
-Примеры:
+Например:
```js
//+ run
@@ -122,6 +121,15 @@ var result = undef || zero || emptyStr || msg || 0;
alert(result); // выведет "Привет!" - первое значение, которое является true
```
+Если все значения "ложные", то `||` возвратит последнее из них:
+
+```js
+//+ run
+
+alert(undefined || '' || false || 0); // 0
+```
+
+
## && (И)
@@ -131,7 +139,7 @@ alert(result); // выведет "Привет!" - первое значение
result = a && b;
```
-**В классическом программировании И возвращает `true`, если оба аргумента истинны, а иначе -- `false`**
+В классическом программировании И возвращает `true`, если оба аргумента истинны, а иначе -- `false`:
```js
//+ run
@@ -141,7 +149,7 @@ alert( true && false); // false
alert( false && false); // false
```
-Пример:
+Пример c `if`:
```js
//+ run
@@ -152,7 +160,7 @@ if (hour == 12 && minute == 30) {
}
```
-Как и в ИЛИ, допустимы любые значения:
+Как и в ИЛИ, в И допустимы любые значения:
```js
//+ run
@@ -163,7 +171,7 @@ if ( 1 && 0 ) { // вычислится как true && false
К И применим тот же принцип "короткого цикла вычислений", но немного по-другому, чем к ИЛИ.
-**Если левый аргумент -- `false`, оператор И возвращает его и заканчивает вычисления, а иначе -- вычисляет и возвращает правый аргумент.**
+**Если левый аргумент -- `false`, оператор И возвращает его и заканчивает вычисления. Иначе -- вычисляет и возвращает правый аргумент.**
Например:
@@ -180,6 +188,15 @@ alert(null && 5); // null
alert(0 && "не важно"); // 0
```
+Можно передать и несколько значений подряд, при этом возвратится первое "ложное" (на котором остановились вычисления), а если его нет -- то последнее:
+
+```js
+//+ run
+alert(1 && 2 && null && 3); // null
+
+alert(1 && 2 && 3); // 3
+```
+
**Приоритет оператора И `&&` больше, чем ИЛИ `||`, т.е. он выполняется раньше.**
Поэтому в следующем коде сначала будет вычислено правое И: `1 && 0 = 0`, а уже потом -- ИЛИ.
@@ -189,6 +206,7 @@ alert(0 && "не важно"); // 0
alert(5 || 1 && 0); // 5
```
+
[warn header="Не используйте `&&` вместо `if`"]
Оператор `&&` в простых случаях можно использовать вместо `if`, например:
@@ -200,7 +218,7 @@ var x = 1;
(x > 0) && alert('Больше');
```
-Действие в правой части `&&` выполнится только в том случае, если до него дойдут вычисления. То есть, если в левой части будет `true`.
+Действие в правой части `&&` выполнится только в том случае, если до него дойдут вычисления. То есть, `alert` сработает, если в левой части будет `true`.
Получился аналог:
@@ -213,7 +231,7 @@ if (x > 0) {
}
```
-Однако, как правило, `if` лучше читается и воспринимается. Он более очевиден, поэтому лучше использовать его. Это, впрочем, относится и к другим неочевидным применениям возможностей языка.
+Однако, как правило, вариант с `if` лучше читается и воспринимается. Он более очевиден, поэтому лучше использовать его. Это, впрочем, относится и к другим неочевидным применениям возможностей языка.
[/warn]
## ! (НЕ)
diff --git a/1-js/2-first-steps/14-types-conversion/1-primitive-conversions-questions/solution.md b/1-js/2-first-steps/13-types-conversion/1-primitive-conversions-questions/solution.md
similarity index 100%
rename from 1-js/2-first-steps/14-types-conversion/1-primitive-conversions-questions/solution.md
rename to 1-js/2-first-steps/13-types-conversion/1-primitive-conversions-questions/solution.md
diff --git a/1-js/2-first-steps/14-types-conversion/1-primitive-conversions-questions/task.md b/1-js/2-first-steps/13-types-conversion/1-primitive-conversions-questions/task.md
similarity index 100%
rename from 1-js/2-first-steps/14-types-conversion/1-primitive-conversions-questions/task.md
rename to 1-js/2-first-steps/13-types-conversion/1-primitive-conversions-questions/task.md
diff --git a/1-js/2-first-steps/14-types-conversion/article.md b/1-js/2-first-steps/13-types-conversion/article.md
similarity index 79%
rename from 1-js/2-first-steps/14-types-conversion/article.md
rename to 1-js/2-first-steps/13-types-conversion/article.md
index 076e54fb..8526f07d 100644
--- a/1-js/2-first-steps/14-types-conversion/article.md
+++ b/1-js/2-first-steps/13-types-conversion/article.md
@@ -9,7 +9,7 @@
Преобразование к логическому значению.
-**Эта глава описывает преобразование только примитивных значений, объекты разбираются далее в учебнике.**
+**Эта глава описывает преобразование только примитивных значений, объекты разбираются далее.**
## Строковое преобразование
@@ -30,6 +30,8 @@ alert(a); // "true"
alert( String(null) === "null" ); // true
```
+Как видно из примеров выше, преобразование происходит наиболее очевидным способом, "как есть": `false` становится `"false"`, `null` -- `"null"`, `undefined` -- `"undefined"` и т.п.
+
Также для явного преобразования применяется оператор `"+"`, у которого один из аргументов строка. В этом случае он приводит к строке и другой аргумент, например:
```js
@@ -42,7 +44,7 @@ alert( "123" + undefined); // "123undefined"
Численное преобразование происходит в математических функциях и выражениях, а также при сравнении данных различных типов (кроме сравнений `===`, `!==`).
-Для преобразования к числу в явном виде можно вызвать `Number(val)`, либо, что короче, поставить перед выражением оператор унарный плюс `"+"`:
+Для преобразования к числу в явном виде можно вызвать `Number(val)`, либо, что короче, поставить перед выражением унарный плюс `"+"`:
```js
var a = +"123"; // 123
@@ -54,14 +56,15 @@ var a = Number("123"); // 123, тот же эффект
`undefined` | `NaN` |
`null` | `0` |
`true / false` | `1 / 0` |
-Строка | Пробельные символы по краям обрезаются. Далее, если остаётся пустая строка, то `0`. Из непустой строки "считывается" число, при ошибке результат: `NaN`. |
+Строка | Пробельные символы по краям обрезаются. Далее, если остаётся пустая строка, то `0`, иначе из непустой строки "считывается" число, при ошибке результат `NaN`. |
Например:
```js
//+ run
-alert( +" \n 123 \n \n"); // 123
+// после обрезания пробельных символов останется "123"
+alert( +" \n 123 \n \n"); // 123
```
Ещё примеры:
@@ -79,13 +82,12 @@ alert( +false); // 0
```js
//+ run
-alert( "\n0\n" == 0 ); // true
+alert( "\n0 " == 0 ); // true
```
-При этом строка `"\n0\n"` преобразуется к числу -- начальные и конечные пробелы игнорируются, получается `0`.
+При этом строка `"\n"` преобразуется к числу, как указано выше: начальные и конечные пробелы обрезаются, получается строка `"0"`, которая равна `0`.
-
-Ещё пример сравнения разных типов:
+С логическими значениями:
```js
//+ run
@@ -118,18 +120,18 @@ alert( "1" == true );
```js
//+ run
-alert(null >= 0); // true, т.к. null преобразуется к 0
-alert(null > 0); // false (не больше), т.к. null преобразуется к 0
+alert(null >= 0); // true, т.к. null преобразуется к 0
+alert(null > 0); // false (не больше), т.к. null преобразуется к 0
alert(null == 0 ); // false (и не равен!), т.к. == рассматривает null особо.
```
-Значение `undefined` вообще вне сравнений:
+Значение `undefined` вообще "несравнимо":
```js
//+ run
-alert(undefined > 0); // false, т.к. undefined -> NaN
+alert(undefined > 0); // false, т.к. undefined -> NaN
alert(undefined == 0); // false, т.к. это undefined (без преобразования)
-alert(undefined < 0); // false, т.к. undefined -> NaN
+alert(undefined < 0); // false, т.к. undefined -> NaN
```
**Для более очевидной работы кода и во избежание ошибок лучше не давать специальным значениям участвовать в сравнениях `> >= < <=`.**
@@ -138,7 +140,7 @@ alert(undefined < 0); // false, т.к. undefined -> NaN
## Логическое преобразование
-Преобразование к `true/false` происходит в логическом контексте, таком как `if(obj)`, `while(obj)` и при применении логических операторов.
+Преобразование к `true/false` происходит в логическом контексте, таком как `if(value)`, и при применении логических операторов.
Все значения, которые интуитивно "пусты", становятся `false`. Их несколько: `0`, пустая строка, `null`, `undefined` и `NaN`.
@@ -172,12 +174,11 @@ alert( !!" " ); // любые непустые строки, даже из пр
**Два значения могут быть равны, но одно из них в логическом контексте `true`, другое -- `false`**.
-Например, равенства в следующем примере верны, так как происходит численное преобразование:
+Например, равенство в следующем примере верно, так как происходит численное преобразование:
```js
//+ run
alert( 0 == "\n0\n" ); // true
-alert( false == " " ); // true
```
...А в логическом контексте левая часть даст `false`, правая -- `true`:
@@ -196,15 +197,12 @@ if ("\n0\n") {
В JavaScript есть три преобразования:
-- Строковое: `String(value)` -- в строковом контексте или при сложении со строкой
-- Численное: `Number(value)` -- в численном контексте, включая унарный плюс `+value`.
+- Строковое: `String(value)` -- в строковом контексте или при сложении со строкой. Работает очевидным образом.
+- Численное: `Number(value)` -- в численном контексте, включая унарный плюс `+value`. Происходит при сравнении разных типов, кроме строгого равенства.
- Логическое: `Boolean(value)` -- в логическом контексте, можно также сделать двойным НЕ: `!!value`.
-**Сравнение не осуществляет преобразование типов в следующих случаях:**
-
-- При сравнении объектов. Две переменные, которые являются объектами равны только, когда ссылаются на один и тот же объект.
-- При сравнении двух строк. Там отдельный алгоритм сравнения. А вот если хоть один операнд -- не строка, то значения будут приведены: `true > "000"` станет `1 > 0`.
-- При проверке равенства с `null` и `undefined`. Они равны друг другу, но не равны чему бы то ни было ещё, этот случай прописан особо в спецификации.
-
+Точные таблицы преобразований даны выше в этой главе.
+
+Особым случаем является проверка равенства с `null` и `undefined`. Они равны друг другу, но не равны чему бы то ни было ещё, этот случай прописан особо в спецификации.
diff --git a/1-js/2-first-steps/15-while-for/1-loop-last-value/solution.md b/1-js/2-first-steps/14-while-for/1-loop-last-value/solution.md
similarity index 100%
rename from 1-js/2-first-steps/15-while-for/1-loop-last-value/solution.md
rename to 1-js/2-first-steps/14-while-for/1-loop-last-value/solution.md
diff --git a/1-js/2-first-steps/15-while-for/1-loop-last-value/task.md b/1-js/2-first-steps/14-while-for/1-loop-last-value/task.md
similarity index 100%
rename from 1-js/2-first-steps/15-while-for/1-loop-last-value/task.md
rename to 1-js/2-first-steps/14-while-for/1-loop-last-value/task.md
diff --git a/1-js/2-first-steps/15-while-for/2-which-value-while/solution.md b/1-js/2-first-steps/14-while-for/2-which-value-while/solution.md
similarity index 100%
rename from 1-js/2-first-steps/15-while-for/2-which-value-while/solution.md
rename to 1-js/2-first-steps/14-while-for/2-which-value-while/solution.md
diff --git a/1-js/2-first-steps/15-while-for/2-which-value-while/task.md b/1-js/2-first-steps/14-while-for/2-which-value-while/task.md
similarity index 100%
rename from 1-js/2-first-steps/15-while-for/2-which-value-while/task.md
rename to 1-js/2-first-steps/14-while-for/2-which-value-while/task.md
diff --git a/1-js/2-first-steps/15-while-for/3-which-value-for/solution.md b/1-js/2-first-steps/14-while-for/3-which-value-for/solution.md
similarity index 100%
rename from 1-js/2-first-steps/15-while-for/3-which-value-for/solution.md
rename to 1-js/2-first-steps/14-while-for/3-which-value-for/solution.md
diff --git a/1-js/2-first-steps/15-while-for/3-which-value-for/task.md b/1-js/2-first-steps/14-while-for/3-which-value-for/task.md
similarity index 100%
rename from 1-js/2-first-steps/15-while-for/3-which-value-for/task.md
rename to 1-js/2-first-steps/14-while-for/3-which-value-for/task.md
diff --git a/1-js/2-first-steps/15-while-for/4-for-even/solution.md b/1-js/2-first-steps/14-while-for/4-for-even/solution.md
similarity index 100%
rename from 1-js/2-first-steps/15-while-for/4-for-even/solution.md
rename to 1-js/2-first-steps/14-while-for/4-for-even/solution.md
diff --git a/1-js/2-first-steps/15-while-for/4-for-even/task.md b/1-js/2-first-steps/14-while-for/4-for-even/task.md
similarity index 100%
rename from 1-js/2-first-steps/15-while-for/4-for-even/task.md
rename to 1-js/2-first-steps/14-while-for/4-for-even/task.md
diff --git a/1-js/2-first-steps/15-while-for/5-replace-for-while/solution.md b/1-js/2-first-steps/14-while-for/5-replace-for-while/solution.md
similarity index 100%
rename from 1-js/2-first-steps/15-while-for/5-replace-for-while/solution.md
rename to 1-js/2-first-steps/14-while-for/5-replace-for-while/solution.md
diff --git a/1-js/2-first-steps/15-while-for/5-replace-for-while/task.md b/1-js/2-first-steps/14-while-for/5-replace-for-while/task.md
similarity index 100%
rename from 1-js/2-first-steps/15-while-for/5-replace-for-while/task.md
rename to 1-js/2-first-steps/14-while-for/5-replace-for-while/task.md
diff --git a/1-js/2-first-steps/15-while-for/6-repeat-until-correct/solution.md b/1-js/2-first-steps/14-while-for/6-repeat-until-correct/solution.md
similarity index 100%
rename from 1-js/2-first-steps/15-while-for/6-repeat-until-correct/solution.md
rename to 1-js/2-first-steps/14-while-for/6-repeat-until-correct/solution.md
diff --git a/1-js/2-first-steps/15-while-for/6-repeat-until-correct/task.md b/1-js/2-first-steps/14-while-for/6-repeat-until-correct/task.md
similarity index 78%
rename from 1-js/2-first-steps/15-while-for/6-repeat-until-correct/task.md
rename to 1-js/2-first-steps/14-while-for/6-repeat-until-correct/task.md
index 6fa1a462..81a09f23 100644
--- a/1-js/2-first-steps/15-while-for/6-repeat-until-correct/task.md
+++ b/1-js/2-first-steps/14-while-for/6-repeat-until-correct/task.md
@@ -6,6 +6,6 @@
Цикл должен спрашивать число пока либо посетитель не введет число, большее `100`, либо не нажмет кнопку Cancel (ESC).
-Предполагается, что посетитель вводит только числа.
+Предполагается, что посетитель вводит только числа, предусматривать обработку нечисловых строк в этой задаче необязательно.
[demo /]
diff --git a/1-js/2-first-steps/16-break-continue/1-list-primes/solution.md b/1-js/2-first-steps/14-while-for/7-list-primes/solution.md
similarity index 100%
rename from 1-js/2-first-steps/16-break-continue/1-list-primes/solution.md
rename to 1-js/2-first-steps/14-while-for/7-list-primes/solution.md
diff --git a/1-js/2-first-steps/16-break-continue/1-list-primes/task.md b/1-js/2-first-steps/14-while-for/7-list-primes/task.md
similarity index 97%
rename from 1-js/2-first-steps/16-break-continue/1-list-primes/task.md
rename to 1-js/2-first-steps/14-while-for/7-list-primes/task.md
index 60d28830..51f8c29f 100644
--- a/1-js/2-first-steps/16-break-continue/1-list-primes/task.md
+++ b/1-js/2-first-steps/14-while-for/7-list-primes/task.md
@@ -1,6 +1,6 @@
# Вывести простые числа
-[importance 4]
+[importance 3]
Натуральное число, большее 1, называется *простым*, если оно ни на что не делится, кроме себя и `1`.
diff --git a/1-js/2-first-steps/14-while-for/article.md b/1-js/2-first-steps/14-while-for/article.md
new file mode 100644
index 00000000..1a41ec84
--- /dev/null
+++ b/1-js/2-first-steps/14-while-for/article.md
@@ -0,0 +1,346 @@
+# Циклы while, for
+
+При написании скриптов зачастую встает задача сделать однотипное действие много раз.
+
+Например, вывести товары из списка один за другим. Или просто перебрать все числа от 1 до 10 и для каждого выполнить одинаковый код.
+
+Для многократного повторения одного участка кода - предусмотрены *циклы*.
+[cut]
+## Цикл while
+
+Цикл `while` имеет вид:
+
+```js
+while (условие) {
+ // код, тело цикла
+}
+```
+
+Пока `условие` верно -- выполняется код из тела цикла.
+
+Например, цикл ниже выводит `i` пока `i < 3`:
+
+```js
+//+ run
+var i = 0;
+while (i < 3) {
+ alert(i);
+ i++;
+}
+```
+
+**Повторение цикла по-научному называется *"итерация"*. Цикл в примере выше совершает три итерации.**
+
+Если бы `i++` в коде выше не было, то цикл выполнялся бы (в теории) вечно. На практике, браузер выведет сообщение о "зависшем" скрипте и посетитель его остановит.
+
+**Бесконечный цикл** можно сделать и проще:
+
+```js
+while (true) {
+ // ...
+}
+```
+
+**Условие в скобках интерпретируется как логическое значение, поэтому вместо `while (i!=0)` обычно пишут `while (i)`**:
+
+```js
+//+ run
+var i = 3;
+*!*
+while (i) { // при i=0 значение в скобках будет false и цикл остановится
+*/!*
+ alert(i);
+ i--;
+}
+```
+
+## Цикл do..while
+
+Проверку условия можно поставить *под* телом цикла, используя специальный синтаксис `do..while`:
+
+```js
+do {
+ // тело цикла
+} while (условие);
+```
+
+Цикл, описанный, таким образом, сначала выполняет тело, а затем проверяет условие.
+
+Например:
+
+```js
+//+ run
+var i = 0;
+do {
+ alert(i);
+ i++;
+} while (i < 3);
+```
+
+Синтаксис `do..while` редко используется, т.к. обычный `while` нагляднее -- в нём не приходится искать глазами условие и ломать голову, почему оно проверяется именно в конце.
+
+
+## Цикл for
+
+Чаще всего применяется цикл `for`. Выглядит он так:
+
+```js
+for (начало; условие; шаг) {
+ // ... тело цикла ...
+}
+```
+
+Пример цикла, который выполняет `alert(i)` для `i` от `0` до `2` включительно (до `3`):
+
+```js
+//+ run
+var i;
+
+for (i=0; i<3; i++) {
+ alert(i);
+}
+```
+
+Здесь:
+
+- **Начало:** `i=0`.
+- **Условие:** `i<3`.
+- **Шаг:** `i++`.
+- **Тело:** `alert(i)`, т.е. код внутри фигурных скобок (они не обязательны, если только одна операция)
+
+
+Цикл выполняется так:
+
+
+- Начало: `i=0` выполняется один-единственный раз, при заходе в цикл.
+- Условие: `i<3` проверяется перед каждой итерацией и при входе в цикл, если оно нарушено, то происходит выход.
+- Тело: `alert(i)`.
+- Шаг: `i++` выполняется после *тела* на каждой итерации, но перед проверкой условия.
+- Идти на шаг 2.
+
+
+Иными, словами, поток выполнения: `начало` -> (если `условие` -> `тело` -> `шаг`) -> (если `условие` -> `тело` -> `шаг`) -> ... и так далее, пока верно `условие`.
+
+[smart]
+В цикле также можно определить переменную:
+
+```js
+//+ run
+for (*!*var*/!* i=0; i<3; i++) {
+ alert(i); // 0, 1, 2
+}
+```
+
+Эта переменная будет видна и за границами цикла, в частности, после окончания цикла `i` станет равно `3`.
+[/smart]
+
+## Пропуск частей for
+
+Любая часть `for` может быть пропущена.
+
+Например, можно убрать `начало`. Цикл в примере ниже полностью идентичен приведённому выше:
+
+```js
+//+ run
+var i = 0;
+
+for (; i<3; i++) {
+ alert(i); // 0, 1, 2
+}
+```
+
+Можно убрать и `шаг`:
+
+```js
+//+ run
+var i = 0;
+
+for (; i<3;) {
+ alert(i);
+ // цикл превратился в аналог while (i<3)
+}
+```
+
+А можно и вообще убрать все, получив бесконечный цикл:
+
+```js
+for (;;) {
+ // будет выполняться вечно
+}
+```
+
+При этом сами точки с запятой `;` обязательно должны присутствовать, иначе будет ошибка синтаксиса.
+
+[smart header="`for..in`"]
+Существует также специальная конструкция `for..in` для перебора свойств объекта.
+
+Мы познакомимся с ней позже, когда будем [говорить об объектах](#for..in).
+[/smart]
+
+
+## Прерывание цикла: break
+
+Выйти из цикла можно не только при проверке условия но и, вообще, в любой момент. Эту возможность обеспечивает директива `break`.
+
+Например, следующий код подсчитывает сумму вводимых чисел до тех пор, пока посетитель их вводит, а затем -- выдаёт:
+
+```js
+var sum = 0;
+
+while(true) {
+
+ var value = +prompt("Введите число", '');
+
+*!*
+ if (!value) break; // (*)
+*/!*
+
+ sum += value;
+
+}
+alert('Сумма: ' + sum);
+```
+
+Директива `break` в строке `(*)`, если посетитель ничего не ввёл, полностью прекращает выполнение цикла и передаёт управление на строку за его телом, то есть на `alert`.
+
+Вообще, сочетание "бесконечный цикл + break" -- отличная штука для тех ситуаций, когда условие, по которому нужно прерваться, находится не в начале-конце цикла, а посередине.
+
+## Следующая итерация: continue [#continue]
+
+Директива `continue` прекращает выполнение *текущей итерации* цикла.
+
+Она -- в некотором роде "младшая сестра" директивы `break`: прерывает не весь цикл, а только текущее выполнение его тела, как будто оно закончилось.
+
+Её используют, если понятно, что на текущем повторе цикла делать больше нечего.
+
+Например, цикл ниже использует `continue`, чтобы не выводить четные значения:
+
+```js
+//+ run
+for (var i = 0; i < 10; i++) {
+
+ *!*if (i % 2 == 0) continue;*/!*
+
+ alert(i);
+}
+```
+
+Для четных `i` срабатывает `continue`, выполнение тела прекращается и управление передается на следующий проход `for`.
+
+[smart header="Директива `continue` позволяет обойтись без скобок"]
+
+Цикл, который обрабатывает только нечётные значения, мог бы выглядеть так:
+
+```js
+for (var i = 0; i < 10; i++) {
+
+ if (i % 2) {
+ alert(i);
+ }
+
+}
+```
+
+С технической точки зрения он полностью идентичен. Действительно, вместо `continue` можно просто завернуть действия в блок `if`. Однако, мы получили дополнительный уровень вложенности фигурных скобок. Если код внутри `if` более длинный, то это ухудшает читаемость, в отличие от варианта с `continue`.
+[/smart]
+
+[warn header="Нельзя использовать break/continue справа от оператора '?'"]
+Обычно мы можем заменить `if` на оператор вопросительный знак `'?'`.
+
+То есть, запись:
+
+```js
+if (условие) {
+ a();
+} else {
+ b();
+}
+```
+
+...Аналогична записи:
+
+```js
+условие ? a() : b();
+```
+
+В обоих случаях в зависимости от условия выполняется либо `a()` либо `b()`.
+
+Но разница состоит в том, что оператор вопросительный знак `'?'`, использованный во второй записи, возвращает значение.
+
+**Синтаксические конструкции, которые не возвращают значений, нельзя использовать в операторе `'?'`.**
+
+К таким относятся большинство конструкций и, в частности, `break/continue`.
+
+Поэтому такой код приведёт к ошибке:
+
+```js
+(i > 5) ? alert(i) : *!*continue*/!*;
+```
+
+Впрочем, как уже говорилось ранее, оператор вопросительный знак `'?'` не стоит использовать таким образом. Это -- всего лишь ещё одна причина, почему для проверки условия предпочтителен `if`.
+[/warn]
+
+## Метки для break/continue
+
+Бывает нужно выйти одновременно из нескольких уровней цикла.
+
+Например, внутри цикла по `i` находится цикл по `j`, и при выполнении некоторого условия мы бы хотели выйти из обоих циклов сразу:
+
+```js
+//+ run
+*!*outer:*/!* for (var i = 0; i < 3; i++) {
+
+ for (var j = 0; j < 3; j++) {
+
+ var input = prompt('Значение в координатах '+i+','+j, '');
+
+ // если отмена ввода или пустая строка -
+ // завершить оба цикла
+ if (!input) *!*break outer*/!*; // (*)
+
+ }
+}
+alert('Готово!');
+```
+
+В коде выше для этого использована *метка*.
+
+Метка имеет вид `"имя:"`, имя должно быть уникальным. Она ставится перед циклом, вот так:
+
+```js
+outer: for (var i = 0; i < 3; i++) { ... }
+```
+
+Можно также выносить ее на отдельную строку:
+
+```js
+outer:
+for (var i = 0; i < 3; i++) { ... }
+```
+
+Вызов `break outer` ищет ближайший внешний цикл с такой меткой и переходит в его конец.
+
+В примере выше это означает, что будет разорван самый внешний цикл и управление перейдёт на `alert`.
+
+Директива `continue` также может быть использована с меткой, в этом случае управление перепрыгнет на следующую итерацию цикла с меткой.
+
+## Итого
+
+JavaScript поддерживает три вида циклов:
+
+- `while` -- проверка условия перед каждым выполнением.
+- `do..while` -- проверка условия после каждого выполнения.
+- `for` -- проверка условия перед каждым выполнением, а также дополнительные настройки.
+
+
+Чтобы организовать бесконечный цикл, используют конструкцию `while(true)`. При этом он, как и любой другой цикл, может быть прерван директивой `break`.
+
+Если на данной итерации цикла делать больше ничего не надо, но полностью прекращать цикл не следует -- используют директиву `continue`.
+
+Обе этих директивы поддерживают "метки", которые ставятся перед циклом. Метки -- единственный способ для `break/continue` повлиять на выполнение внешнего цикла.
+
+Заметим, что метки не позволяют прыгнуть на произвольное место кода, в JavaScript нет такой возможности.
+
+
+
+
diff --git a/1-js/2-first-steps/17-switch/1-rewrite-switch-if-else/solution.md b/1-js/2-first-steps/15-switch/1-rewrite-switch-if-else/solution.md
similarity index 100%
rename from 1-js/2-first-steps/17-switch/1-rewrite-switch-if-else/solution.md
rename to 1-js/2-first-steps/15-switch/1-rewrite-switch-if-else/solution.md
diff --git a/1-js/2-first-steps/17-switch/1-rewrite-switch-if-else/task.md b/1-js/2-first-steps/15-switch/1-rewrite-switch-if-else/task.md
similarity index 100%
rename from 1-js/2-first-steps/17-switch/1-rewrite-switch-if-else/task.md
rename to 1-js/2-first-steps/15-switch/1-rewrite-switch-if-else/task.md
diff --git a/1-js/2-first-steps/17-switch/2-rewrite-if-switch/solution.md b/1-js/2-first-steps/15-switch/2-rewrite-if-switch/solution.md
similarity index 100%
rename from 1-js/2-first-steps/17-switch/2-rewrite-if-switch/solution.md
rename to 1-js/2-first-steps/15-switch/2-rewrite-if-switch/solution.md
diff --git a/1-js/2-first-steps/17-switch/2-rewrite-if-switch/task.md b/1-js/2-first-steps/15-switch/2-rewrite-if-switch/task.md
similarity index 100%
rename from 1-js/2-first-steps/17-switch/2-rewrite-if-switch/task.md
rename to 1-js/2-first-steps/15-switch/2-rewrite-if-switch/task.md
diff --git a/1-js/2-first-steps/17-switch/article.md b/1-js/2-first-steps/15-switch/article.md
similarity index 100%
rename from 1-js/2-first-steps/17-switch/article.md
rename to 1-js/2-first-steps/15-switch/article.md
diff --git a/1-js/2-first-steps/15-while-for/article.md b/1-js/2-first-steps/15-while-for/article.md
deleted file mode 100644
index e1a60635..00000000
--- a/1-js/2-first-steps/15-while-for/article.md
+++ /dev/null
@@ -1,179 +0,0 @@
-# Циклы while, for
-
-При написании скриптов зачастую встает задача сделать однотипное действие много раз.
-
-Например, вывести товары из списка один за другим. Или просто перебрать все числа от 1 до 10 и для каждого выполнить одинаковый код.
-
-Для многократного повторения одного участка кода - предусмотрены *циклы*.
-[cut]
-## Цикл while
-
-Цикл `while` имеет вид:
-
-```js
-while (условие) {
- // код, тело цикла
-}
-```
-
-Пока `условие` верно -- выполняется код из тела цикла.
-
-Например, цикл ниже выводит `i` пока `i < 3`:
-
-```js
-//+ run
-var i = 0;
-while (i < 3) {
- alert(i);
- i++;
-}
-```
-
-**Повторение цикла по-научному называется *"итерация"*. Цикл в примере выше совершает три итерации.**
-
-Если бы `i++` в коде выше не было, то цикл выполнялся бы (в теории) вечно. На практике, браузер выведет сообщение о "зависшем" скрипте и посетитель его остановит.
-
-**Бесконечный цикл** можно сделать и проще:
-
-```js
-while (true) {
- // ...
-}
-```
-
-**Условие в скобках интерпретируется как логическое значение, поэтому вместо `while (i!=0)` обычно пишут `while (i)`**:
-
-```js
-//+ run
-var i = 3;
-*!*
-while (i) { // при i=0 значение в скобках будет false и цикл остановится
-*/!*
- alert(i);
- i--;
-}
-```
-
-## Цикл do..while
-
-Проверку условия можно поставить *под* телом цикла, используя специальный синтаксис `do..while`:
-
-```js
-do {
- // тело цикла
-} while (условие);
-```
-
-Цикл, описанный, таким образом, сначала выполняет тело, а затем проверяет условие.
-
-Например:
-
-```js
-//+ run
-var i = 0;
-do {
- alert(i);
- i++;
-} while (i < 3);
-```
-
-Синтаксис `do..while` редко используется, т.к. обычный `while` нагляднее -- в нём не приходится искать глазами условие и ломать голову, почему оно проверяется именно в конце.
-
-
-## Цикл for
-
-Чаще всего применяется цикл `for`. Выглядит он так:
-
-```js
-for (начало; условие; шаг) {
- // ... тело цикла ...
-}
-```
-
-Пример цикла, который выполняет `alert(i)` для `i` от `0` до `2` включительно (до `3`):
-
-```js
-//+ run
-var i;
-
-for (i=0; i<3; i++) {
- alert(i);
-}
-```
-
-Здесь:
-
-- **Начало:** `i=0`.
-- **Условие:** `i<3`.
-- **Шаг:** `i++`.
-- **Тело:** `alert(i)`, т.е. код внутри фигурных скобок (они не обязательны, если только одна операция)
-
-
-Цикл выполняется так:
-
-
-- Начало: `i=0` выполняется один-единственный раз, при заходе в цикл.
-- Условие: `i<3` проверяется перед каждой итерацией и при входе в цикл, если оно нарушено, то происходит выход.
-- Тело: `alert(i)`.
-- Шаг: `i++` выполняется после *тела* на каждой итерации, но перед проверкой условия.
-- Идти на шаг 2.
-
-
-Иными, словами, поток выполнения: `начало` -> (если `условие` -> `тело` -> `шаг`) -> (если `условие` -> `тело` -> `шаг`) -> ... и так далее, пока верно `условие`.
-
-[smart]
-В цикле также можно определить переменную:
-
-```js
-//+ run
-for (*!*var*/!* i=0; i<3; i++) {
- alert(i); // 0, 1, 2
-}
-```
-
-Эта переменная будет видна и за границами цикла, в частности, после окончания цикла `i` станет равно `3`.
-[/smart]
-
-## Пропуск частей for
-
-Любая часть `for` может быть пропущена.
-
-Например, можно убрать `начало`. Цикл в примере ниже полностью идентичен приведённому выше:
-
-```js
-//+ run
-var i = 0;
-
-for (; i<3; i++) {
- alert(i); // 0, 1, 2
-}
-```
-
-Можно убрать и `шаг`:
-
-```js
-//+ run
-var i = 0;
-
-for (; i<3;) {
- alert(i);
- // цикл превратился в аналог while (i<3)
-}
-```
-
-А можно и вообще убрать все, получив бесконечный цикл:
-
-```js
-for (;;) {
- // будет выполняться вечно
-}
-```
-
-При этом сами точки с запятой `;` обязательно должны присутствовать, иначе будет ошибка синтаксиса.
-
-[smart header="`for..in`"]
-Существует также специальная конструкция `for..in` для перебора свойств объекта.
-
-Мы познакомимся с ней позже, когда будем [говорить об объектах](#for..in).
-[/smart]
-
diff --git a/1-js/2-first-steps/16-break-continue/article.md b/1-js/2-first-steps/16-break-continue/article.md
deleted file mode 100644
index 7a4b2adc..00000000
--- a/1-js/2-first-steps/16-break-continue/article.md
+++ /dev/null
@@ -1,198 +0,0 @@
-# Директивы break и continue
-
-Для более гибкого управления циклом используются директивы `break` и `continue`.
-[cut]
-## Выход: break
-
-Выйти из цикла можно не только при проверке условия но и, вообще, в любой момент. Эту возможность обеспечивает директива `break`.
-
-Например, бесконечный цикл в примере прекратит выполнение при `i==5`:
-
-```js
-var i=0;
-
-while(1) {
- i++;
-
- *!*if (i==5) break;*/!*
-
- alert(i);
-}
-
-alert('Последняя i = '+ i ); // 5 (*)
-```
-
-Выполнение продолжится со строки `(*)`, следующей за циклом.
-
-## Следующая итерация: continue [#continue]
-
-Директива `continue` прекращает выполнение *текущей итерации* цикла. Например, цикл ниже не выводит четные значения:
-
-```js
-//+ run
-for (var i = 0; i < 10; i++) {
-
- *!*if (i % 2 == 0) continue;*/!*
-
- alert(i);
-}
-```
-
-Для четных `i` срабатывает `continue`, выполнение блока прекращается и управление передается на `for`.
-
-[smart header="Совет по стилю"]
-
-Как правило, `continue` и используют, чтобы не обрабатывать определенные значения в цикле.
-
-Цикл, который обрабатывает только часть значений, мог бы выглядеть так:
-
-```js
-for (var i = 0; i < 10; i++) {
-
- if ( checkValue(i) ) {
- // функция checkValue проверяет, подходит ли i
-
- // ...
- // ... обработка
- // ... этого
- // ... значения
- // ... цикла
- // ...
-
- }
-}
-```
-
-Все хорошо, но мы получили *дополнительный уровень вложенности фигурных скобок, без которого можно и нужно обойтись*.
-
-Гораздо лучше здесь использовать `continue`:
-
-```js
-for (var i = 0; i < 10; i++) {
-
- *!*if ( !checkValue(i) ) continue;*/!*
-
- // здесь мы точно знаем, что i подходит
-
- // ...
- // ... обработка
- // ... этого
- // ... значения
- // ... цикла
- // ...
-
-}
-```
-
-[/smart]
-
-[warn header="Нельзя использовать break/continue справа от оператора '?'"]
-Обычно мы можем заменить `if` на оператор вопросительный знак `'?'`.
-
-То есть, запись:
-
-```js
-if (условие) {
- a();
-} else {
- b();
-}
-```
-
-..Аналогична записи:
-
-```js
-условие ? a() : b();
-```
-
-В обоих случаях в зависимости от условия выполняется либо `a()` либо `b()`.
-
-Но разница состоит в том, что оператор вопросительный знак `'?'`, использованный во второй записи, возвращает значение.
-
-**Синтаксические конструкции, которые не возвращают значений, нельзя использовать в операторе `'?'`.** К таким относятся большинство конструкций и, в частности, `break/continue`.
-
-Поэтому такой код приведёт к ошибке:
-
-```js
-(i > 5) ? alert(i) : *!*continue*/!*;
-```
-
-[/warn]
-
-## Метки
-
-Бывает нужно выйти одновременно из нескольких уровней цикла.
-
-Представим, что нужно ввести значения точек. У каждой точки есть две координаты `(i, j)`. Цикл для ввода значений `i,j = 0..2` может выглядеть так:
-
-```js
-//+ run
-for (var i = 0; i < 3; i++) {
-
- for (var j = 0; j < 3; j++) {
-
- var input = prompt("Значение в координатах " + i + "," + j, "");
-
- if (input == null) *!*break*/!*; // (*)
-
- }
-}
-alert('Готово!');
-```
-
-Здесь `break` используется, чтобы прервать ввод, если посетитель нажал на `Отмена`. Но обычный вызов `break` в строке `(*)` не может прервать два цикла сразу. Как же прервать ввод полностью? Один из способов -- поставить *метку*.
-
-Метка имеет вид `"имя:"`, имя должно быть уникальным. Она ставится перед циклом, вот так:
-
-```js
-outer: for (var i = 0; i < 3; i++) { ... }
-```
-
-Можно также выносить ее на отдельную строку. Вызов `break outer` прерывает управление цикла с такой меткой, вот так:
-
-```js
-//+ run
-outer:
-for (var i = 0; i < 3; i++) {
-
- for (var j = 0; j < 3; j++) {
-
- var input = prompt('Значение в координатах '+i+','+j, '');
-
- if (input == null) *!*break outer*/!*; // (*)
-
- }
-}
-alert('Готово!');
-```
-
-Директива `continue` также может быть использована с меткой. Управление перепрыгнет на следующую итерацию цикла с меткой.
-
-**Метки можно ставить в том числе на блок, без цикла:**
-
-```js
-//+ run
-my: {
-
- for (;;) {
- for (i=0; i<10; i++) {
- if (i>4) break my;
- }
- }
-
- some_code; // произвольный участок кода
-
-}
-alert("После my"); // (*)
-```
-
-В примере выше, `break` перепрыгнет через `some_code`, выполнение продолжится сразу после блока `my`, со строки `(*)`. Возможность ставить метку на блоке используется редко. Обычно метки ставятся перед циклом.
-
-[smart header="Goto?"]
-В некоторых языках программирования есть оператор `goto`, который может передавать управление на любой участок программы.
-
-Операторы `break/continue` более ограниченны. Они работают только внутри циклов, и метка должна быть не где угодно, а выше по уровню вложенности.
-
-В JavaScript нет `goto`.
-[/smart]
-
diff --git a/1-js/2-first-steps/18-function-basics/1-if-else-required/solution.md b/1-js/2-first-steps/16-function-basics/1-if-else-required/solution.md
similarity index 100%
rename from 1-js/2-first-steps/18-function-basics/1-if-else-required/solution.md
rename to 1-js/2-first-steps/16-function-basics/1-if-else-required/solution.md
diff --git a/1-js/2-first-steps/18-function-basics/1-if-else-required/task.md b/1-js/2-first-steps/16-function-basics/1-if-else-required/task.md
similarity index 100%
rename from 1-js/2-first-steps/18-function-basics/1-if-else-required/task.md
rename to 1-js/2-first-steps/16-function-basics/1-if-else-required/task.md
diff --git a/1-js/2-first-steps/18-function-basics/2-rewrite-function-question-or/solution.md b/1-js/2-first-steps/16-function-basics/2-rewrite-function-question-or/solution.md
similarity index 100%
rename from 1-js/2-first-steps/18-function-basics/2-rewrite-function-question-or/solution.md
rename to 1-js/2-first-steps/16-function-basics/2-rewrite-function-question-or/solution.md
diff --git a/1-js/2-first-steps/18-function-basics/2-rewrite-function-question-or/task.md b/1-js/2-first-steps/16-function-basics/2-rewrite-function-question-or/task.md
similarity index 100%
rename from 1-js/2-first-steps/18-function-basics/2-rewrite-function-question-or/task.md
rename to 1-js/2-first-steps/16-function-basics/2-rewrite-function-question-or/task.md
diff --git a/1-js/2-first-steps/18-function-basics/3-min/solution.md b/1-js/2-first-steps/16-function-basics/3-min/solution.md
similarity index 100%
rename from 1-js/2-first-steps/18-function-basics/3-min/solution.md
rename to 1-js/2-first-steps/16-function-basics/3-min/solution.md
diff --git a/1-js/2-first-steps/18-function-basics/3-min/task.md b/1-js/2-first-steps/16-function-basics/3-min/task.md
similarity index 100%
rename from 1-js/2-first-steps/18-function-basics/3-min/task.md
rename to 1-js/2-first-steps/16-function-basics/3-min/task.md
diff --git a/1-js/2-first-steps/18-function-basics/4-pow/solution.md b/1-js/2-first-steps/16-function-basics/4-pow/solution.md
similarity index 100%
rename from 1-js/2-first-steps/18-function-basics/4-pow/solution.md
rename to 1-js/2-first-steps/16-function-basics/4-pow/solution.md
diff --git a/1-js/2-first-steps/18-function-basics/4-pow/task.md b/1-js/2-first-steps/16-function-basics/4-pow/task.md
similarity index 100%
rename from 1-js/2-first-steps/18-function-basics/4-pow/task.md
rename to 1-js/2-first-steps/16-function-basics/4-pow/task.md
diff --git a/1-js/2-first-steps/18-function-basics/article.md b/1-js/2-first-steps/16-function-basics/article.md
similarity index 100%
rename from 1-js/2-first-steps/18-function-basics/article.md
rename to 1-js/2-first-steps/16-function-basics/article.md
diff --git a/1-js/2-first-steps/18-function-basics/style.png b/1-js/2-first-steps/16-function-basics/style.png
similarity index 100%
rename from 1-js/2-first-steps/18-function-basics/style.png
rename to 1-js/2-first-steps/16-function-basics/style.png
diff --git a/1-js/2-first-steps/19-recursion/1-sum-to/solution.md b/1-js/2-first-steps/17-recursion/1-sum-to/solution.md
similarity index 100%
rename from 1-js/2-first-steps/19-recursion/1-sum-to/solution.md
rename to 1-js/2-first-steps/17-recursion/1-sum-to/solution.md
diff --git a/1-js/2-first-steps/19-recursion/1-sum-to/task.md b/1-js/2-first-steps/17-recursion/1-sum-to/task.md
similarity index 100%
rename from 1-js/2-first-steps/19-recursion/1-sum-to/task.md
rename to 1-js/2-first-steps/17-recursion/1-sum-to/task.md
diff --git a/1-js/2-first-steps/19-recursion/2-factorial/solution.md b/1-js/2-first-steps/17-recursion/2-factorial/solution.md
similarity index 100%
rename from 1-js/2-first-steps/19-recursion/2-factorial/solution.md
rename to 1-js/2-first-steps/17-recursion/2-factorial/solution.md
diff --git a/1-js/2-first-steps/19-recursion/2-factorial/task.md b/1-js/2-first-steps/17-recursion/2-factorial/task.md
similarity index 100%
rename from 1-js/2-first-steps/19-recursion/2-factorial/task.md
rename to 1-js/2-first-steps/17-recursion/2-factorial/task.md
diff --git a/1-js/2-first-steps/19-recursion/3-fibonacci-numbers/solution.md b/1-js/2-first-steps/17-recursion/3-fibonacci-numbers/solution.md
similarity index 100%
rename from 1-js/2-first-steps/19-recursion/3-fibonacci-numbers/solution.md
rename to 1-js/2-first-steps/17-recursion/3-fibonacci-numbers/solution.md
diff --git a/1-js/2-first-steps/19-recursion/3-fibonacci-numbers/task.md b/1-js/2-first-steps/17-recursion/3-fibonacci-numbers/task.md
similarity index 100%
rename from 1-js/2-first-steps/19-recursion/3-fibonacci-numbers/task.md
rename to 1-js/2-first-steps/17-recursion/3-fibonacci-numbers/task.md
diff --git a/1-js/2-first-steps/19-recursion/article.md b/1-js/2-first-steps/17-recursion/article.md
similarity index 100%
rename from 1-js/2-first-steps/19-recursion/article.md
rename to 1-js/2-first-steps/17-recursion/article.md
diff --git a/1-js/2-first-steps/20-function-declaration-expression/article.md b/1-js/2-first-steps/18-function-declaration-expression/article.md
similarity index 100%
rename from 1-js/2-first-steps/20-function-declaration-expression/article.md
rename to 1-js/2-first-steps/18-function-declaration-expression/article.md
diff --git a/1-js/2-first-steps/21-named-function-expression/1-nfe-check/solution.md b/1-js/2-first-steps/19-named-function-expression/1-nfe-check/solution.md
similarity index 100%
rename from 1-js/2-first-steps/21-named-function-expression/1-nfe-check/solution.md
rename to 1-js/2-first-steps/19-named-function-expression/1-nfe-check/solution.md
diff --git a/1-js/2-first-steps/21-named-function-expression/1-nfe-check/task.md b/1-js/2-first-steps/19-named-function-expression/1-nfe-check/task.md
similarity index 100%
rename from 1-js/2-first-steps/21-named-function-expression/1-nfe-check/task.md
rename to 1-js/2-first-steps/19-named-function-expression/1-nfe-check/task.md
diff --git a/1-js/2-first-steps/21-named-function-expression/article.md b/1-js/2-first-steps/19-named-function-expression/article.md
similarity index 100%
rename from 1-js/2-first-steps/21-named-function-expression/article.md
rename to 1-js/2-first-steps/19-named-function-expression/article.md
diff --git a/1-js/2-first-steps/22-javascript-specials/article.md b/1-js/2-first-steps/20-javascript-specials/article.md
similarity index 100%
rename from 1-js/2-first-steps/22-javascript-specials/article.md
rename to 1-js/2-first-steps/20-javascript-specials/article.md
diff --git a/1-js/2-first-steps/6-types-intro/article.md b/1-js/2-first-steps/6-types-intro/article.md
index fcead2b2..5bb17032 100644
--- a/1-js/2-first-steps/6-types-intro/article.md
+++ b/1-js/2-first-steps/6-types-intro/article.md
@@ -33,6 +33,8 @@ alert( "нечисло" * 2 ); // NaN, ошибка
Эти значения формально принадлежат типу "число", хотя, конечно, числами в их обычном понимании не являются.
+Особенности работы с числами в JavaScript разобраны в главе [](/number).
+
## Строка "string"
```js
@@ -46,6 +48,8 @@ str = 'Одинарные кавычки тоже подойдут';
В некоторых языках программирования есть специальный тип данных для одного символа. Например, в языке С это `char`. В JavaScript есть только тип "строка" `string`. Что, надо сказать, вполне удобно.
[/smart]
+Более подробно со строками мы познакомимся в главе [](/string).
+
## Булевый (логический) тип "boolean"
У него всего два значения: `true` (истина) и `false` (ложь).
@@ -101,7 +105,7 @@ alert(x); // "undefined"
Особняком стоит шестой тип: *"объекты"*. К нему относятся, например, даты, функции, он используется для коллекций данных и для объявления более сложных сущностей.
-Позже мы вернёмся к этому типу и рассмотрим его принципиальные отличия от примитивов.
+Позже, в главе [про объекты](/object) мы вернёмся к этому типу и рассмотрим его принципиальные отличия от примитивов.
## Итого
diff --git a/1-js/2-first-steps/8-operators/1-increment-order/solution.md b/1-js/2-first-steps/7-operators/1-increment-order/solution.md
similarity index 100%
rename from 1-js/2-first-steps/8-operators/1-increment-order/solution.md
rename to 1-js/2-first-steps/7-operators/1-increment-order/solution.md
diff --git a/1-js/2-first-steps/8-operators/1-increment-order/task.md b/1-js/2-first-steps/7-operators/1-increment-order/task.md
similarity index 100%
rename from 1-js/2-first-steps/8-operators/1-increment-order/task.md
rename to 1-js/2-first-steps/7-operators/1-increment-order/task.md
diff --git a/1-js/2-first-steps/8-operators/2-assignment-result/solution.md b/1-js/2-first-steps/7-operators/2-assignment-result/solution.md
similarity index 100%
rename from 1-js/2-first-steps/8-operators/2-assignment-result/solution.md
rename to 1-js/2-first-steps/7-operators/2-assignment-result/solution.md
diff --git a/1-js/2-first-steps/8-operators/2-assignment-result/task.md b/1-js/2-first-steps/7-operators/2-assignment-result/task.md
similarity index 100%
rename from 1-js/2-first-steps/8-operators/2-assignment-result/task.md
rename to 1-js/2-first-steps/7-operators/2-assignment-result/task.md
diff --git a/1-js/2-first-steps/8-operators/article.md b/1-js/2-first-steps/7-operators/article.md
similarity index 72%
rename from 1-js/2-first-steps/8-operators/article.md
rename to 1-js/2-first-steps/7-operators/article.md
index 7aecc255..dcd0d700 100644
--- a/1-js/2-first-steps/8-operators/article.md
+++ b/1-js/2-first-steps/7-operators/article.md
@@ -1,11 +1,18 @@
# Основные операторы
Для работы с переменными, со значениями, JavaScript поддерживает все стандартные операторы, большинство которых есть и в других языках программирования.
+
+Несколько операторов мы знаем со школы -- это обычные сложение `+`, умножение `*`, вычитание и так далее.
+
+В этой главе мы сконцентрируемся на операторах, которые в на математике не проходят и на их особенностях именно в JavaScript.
[cut]
## Термины: "унарный", "бинарный", "операнд"
У операторов есть своя терминология, которая используется во всех языках программирования.
+
+Прежде, чем мы двинемся дальше -- несколько терминов, чтобы понимать, о чём речь.
+
- *Операнд* -- то, к чему применяется оператор. Например: `5 * 2` -- оператор умножения с левым и правым операндами. Другое название: "аргумент оператора".
- *Унарным* называется оператор, который применяется к одному выражению. Например, оператор унарный минус `"-"` меняет знак числа на противоположный:
@@ -13,9 +20,11 @@
```js
//+ run
var x = 1;
-alert( -x ); // -1, унарный минус
-alert( -(x+2) ); // -3, унарный минус применён к результату сложения x+2
-alert( -(-3) ); // 3
+
+*!*
+x = -x;
+*/!*
+alert( x ); // -1, применили унарный минус
```
@@ -26,54 +35,23 @@ alert( -(-3) ); // 3
var x = 1, y = 3;
alert( y - x ); // 2, бинарный минус
```
-
-Некоторые операторы, например, вычитание `"-"` и сложение `"+"`, бывают в двух вариантах: унарный -- при применении к одному операнду, и бинарный -- к двум.
-## Арифметические операторы
+## Сложение строк, бинарный +
-Базовые арифметические операторы знакомы нам с детства: это плюс `+`, минус `-`, умножить `*`, поделить `/`.
+Обычно при помощи плюса `'+'` складывают числа.
-Например:
-
-```js
-//+ run
-alert(2 + 2); // 4
-```
-
-Или чуть сложнее:
-
-```js
-//+ run
-var i = 2;
-
-i = (2 + i) * 3 / i;
-
-alert(i); // 6
-```
-
-**Более редкий арифметический оператор `%` интересен тем, что никакого отношения к процентам не имеет. Его результат `a % b` -- это остаток от деления `a` на `b`.**
-
-Например:
-
-```js
-//+ run
-alert(5 % 2); // 1, остаток от деления 5 на 2
-alert(8 % 3); // 2, остаток от деления 8 на 3
-alert(6 % 3); // 0, остаток от деления 6 на 3
-```
-
-### Сложение строк, бинарный +
-
-Если бинарный оператор `+` применить к строкам, то он их объединяет в одну:
+Но если бинарный оператор `'+'` применить к строкам, то он их объединяет в одну:
```js
var a = "моя" + "строка";
alert(a); // моястрока
```
+Иначе говорят, что "плюс производит конкатенацию (сложение) строк".
+
**Если хотя бы один аргумент является строкой, то второй будет также преобразован к строке!**
Причем не важно, справа или слева находится операнд-строка, в любом случае нестроковый аргумент будет преобразован. Например:
@@ -84,12 +62,6 @@ alert( '1' + 2 ); // "12"
alert( 2 + '1' ); // "21"
```
-[smart]
-Для сложения строк в программировании используется специальный термин "конкатенация" (от англ. concat).
-
-В примерах выше оператор `'+'` производил конкатенацию строк.
-[/smart]
-
**Это приведение к строке -- особенность исключительно бинарного оператора `"+"`.**
Остальные арифметические операторы работают только с числами и всегда приводят аргументы к числу.
@@ -98,18 +70,20 @@ alert( 2 + '1' ); // "21"
```js
//+ run
-alert( '1' - 2 ); // -1
-alert( 6 / '2'); // 3
+alert( 2 - '1' ); // 1
+alert( 6 / '2'); // 3
```
-### Унарный плюс +
-Унарный, то есть применённый к одному значению, плюс как арифметический оператор ничего не делает:
+
+### Преобразование к числу, унарный плюс +
+
+Унарный, то есть применённый к одному значению, плюс ничего не делает с числами:
```js
//+ run
alert( +1 ); // 1
-alert( +(1-2) ); // -1
+alert( +(1 - 2) ); // -1
```
Как видно, плюс ничего не изменил в выражениях. Результат -- такой же, как и без него.
@@ -118,52 +92,69 @@ alert( +(1-2) ); // -1
Например, когда мы получаем значения из HTML-полей или от пользователя, то они обычно в форме строк.
-А что, если их нужно сложить? Бинарный плюс сложит их как строки:
+А что, если их нужно, к примеру, сложить? Бинарный плюс сложит их как строки:
```js
//+ run
-var a = "2";
-var b = "3";
+var apples = "2";
+var oranges = "3";
-alert( a + b ); // "23", так как бинарный плюс складывает строки
+alert( apples + oranges ); // "23", так как бинарный плюс складывает строки
```
Поэтому используем унарный плюс, чтобы преобразовать к числу:
```js
//+ run
-var a = "2";
-var b = "3";
+var apples = "2";
+var oranges = "3";
-alert( +a + +b); // 5, число, оба операнда предварительно преобразованы в числа
+alert( +apples + +oranges); // 5, число, оба операнда предварительно преобразованы в числа
```
+С точки зрения математики такое изобилие плюсов может показаться странном. С точки зрения программирования -- никаких разночтений: сначала выполнятся унарные плюсы, приведут строки к числам, а затем -- бинарный `'+'` их сложит.
+
+Почему унарные плюсы выполнились до бинарного сложения? Как мы сейчас увидим, дело в их приоритете.
+
+## Приоритет
+
+
+В том случае, если в выражении есть несколько операторов -- порядок их выполнения определяется *приоритетом*.
+
+Из школы мы знаем, что умножение в выражении `2 * 2 + 1` выполнится раньше сложения, т.к. его *приоритет* выше, а скобки явно задают порядок выполнения. Но в JavaScript -- гораздо больше операторов, поэтому существует целая [таблица приоритетов](https://developer.mozilla.org/en/JavaScript/Reference/operators/operator_precedence).
+
+Она содержит как уже пройденные операторы, так и те, которые мы еще не проходили. В ней каждому оператору задан числовой приоритет. Тот, у кого число меньше -- выполнится раньше. Если приоритет одинаковый, то порядок выполнения -- слева направо.
+
+Отрывок из таблицы:
+
+
+... | ... | ... |
+4 | унарный плюс | `+` |
+4 | унарный минус | `-` |
+5 | умножение | `*` |
+5 | деление | `/` |
+6 | сложение | `+` |
+6 | вычитание | `-` |
+17 | присвоение | `=` |
+... | ... | ... |
+
+
+Так как "унарный плюс" имеет приоритет `4`, выше, чем `6` у обычного "сложения", то в выражении `+apples + +oranges` сначала сработали плюсы у `apples` и `oranges`, а затем уже обычное сложение.
+
## Присваивание
-Оператор присваивания выглядит как знак равенства `=`:
+Обратим внимание, в таблице приоритетов также есть оператор присваивания `=`.
+
+У него -- один из самых низких приоритетов: `17`.
+
+Именно поэтому, когда переменную чему-либо присваивают, например, `x = 2 * 2 + 1` сначала выполнится арифметика, а уже затем -- произойдёт присвоение `=`.
```js
-var i = 1 + 2;
+var x = 2 * 2 + 1;
-alert(i); // 3
+alert(x); // 5
```
-Он вычисляет выражение, которое находится справа, и присваивает результат переменной. Это выражение может быть достаточно сложным и включать в себя любые другие переменные:
-
-```js
-//+ run
-var a = 1;
-var b = 2;
-
-*!*
-a = b + a + 3; // (*)
-*/!*
-
-alert(a); // 6
-```
-
-В строке `(*)` сначала произойдет вычисление, использующее текущее значение `a` (т.е. `1`), после чего результат перезапишет старое значение `a`.
-
**Возможно присваивание по цепочке:**
```js
@@ -182,7 +173,9 @@ alert(c); // 4
Такое присваивание работает справа-налево, то есть сначала вычислятся самое правое выражение `2+2`, присвоится в `c`, затем выполнится `b = c` и, наконец, `a = b`.
[smart header="Оператор `\"=\"` возвращает значение"]
-Все операторы возвращают значение. Вызов `x = выражение` записывает выражение в `x`, а затем возвращает его. Благодаря этому присваивание можно использовать как часть более сложного выражения:
+Все операторы возвращают значение. Вызов `x = выражение` не является исключением.
+
+Он записывает выражение в `x`, а затем возвращает его. Благодаря этому присваивание можно использовать как часть более сложного выражения:
```js
//+ run
@@ -205,29 +198,21 @@ alert(c); // 0
[/smart]
-## Приоритет
+## Взятие остатка %
-В том случае, если в выражении есть несколько операторов - порядок их выполнения определяется *приоритетом*.
+Оператор взятия остатка `%` интересен тем, что, несмотря на обозначение, никакого отношения к процентам не имеет.
-Из школы мы знаем, что умножение в выражении `2 * 2 + 1` выполнится раньше сложения, т.к. его *приоритет* выше, а скобки явно задают порядок выполнения. Но в JavaScript -- гораздо больше операторов, поэтому существует целая [таблица приоритетов](https://developer.mozilla.org/en/JavaScript/Reference/operators/operator_precedence).
+Его результат `a % b` -- это остаток от деления `a` на `b`.
-Она содержит как уже пройденные операторы, так и те, которые мы еще не проходили. В ней каждому оператору задан числовой приоритет. Тот, у кого число меньше -- выполнится раньше. Если приоритет одинаковый, то порядок выполнения -- слева направо.
+Например:
-Отрывок из таблицы:
+```js
+//+ run
+alert(5 % 2); // 1, остаток от деления 5 на 2
+alert(8 % 3); // 2, остаток от деления 8 на 3
+alert(6 % 3); // 0, остаток от деления 6 на 3
+```
-
-... | ... | ... |
-5 | умножение | `*` |
-5 | деление | `/` |
-6 | сложение | `+` |
-6 | вычитание | `-` |
-17 | присвоение | `=` |
-... | ... | ... |
-
-
-Посмотрим на таблицу в действии.
-
-В выражении `x = 2 * 2 + 1` есть три оператора: присвоение `=`, умножение `*` и сложение `+`. Приоритет умножения `*` равен `5`, оно выполнится первым, затем произойдёт сложение `+`, у которого приоритет `6`, и после них -- присвоение `=`, с приоритетом 17.
## Инкремент/декремент: ++, --
@@ -324,7 +309,7 @@ alert( i++ ); // 0
-**Инкремент/декремент можно использовать в любых выражениях.**
+[smart header="Инкремент/декремент можно использовать в любых выражениях"]
При этом он имеет более высокий приоритет и выполняется раньше, чем арифметические операции:
@@ -352,6 +337,7 @@ var i = 1;
alert( 2 * i );
i++;
```
+[/smart]
## Побитовые операторы
@@ -370,11 +356,11 @@ i++;
ZERO-FILL RIGHT SHIFT(правый сдвиг с заполнением нулями) ( `>>>` )
-Вы можете более подробно почитать о них в отдельной статье [](/bitwise-operators).
+Они используются редко, поэтому вынесены в отдельную главу [](/bitwise-operators).
-## Вызов операторов с присваиванием
+## Сокращённая арифметика с присваиванием
Часто нужно применить оператор к переменной и сохранить результат в ней же, например:
@@ -384,9 +370,7 @@ n = n + 5;
n = n * 2;
```
-Эту запись можно укоротить при помощи совмещённых операторов: +=, -=, *=, /=, >>=, <<=, >>>=, &=, |=, ^=
.
-
-Вот так:
+Эту запись можно укоротить при помощи совмещённых операторов, вот так:
```js
//+ run
@@ -397,13 +381,24 @@ n *= 2; // теперь n=14 (работает как n = n * 2)
alert(n); // 14
```
-Все эти операторы имеют в точности такой же приоритет, как обычное присваивание, то есть выполняются после большинства других операций.
+Так можно сделать для операторов `+,-,*,/` и бинарных `<<,>>,>>>,&,|,^`.
+Вызов с присваиванием имеет в точности такой же приоритет, как обычное присваивание, то есть выполнится после большинства других операций:
+
+```js
+//+ run
+var n = 2;
+n *= 3 + 5;
+
+alert(n); // 16 (n = 2 * 8)
+```
## Оператор запятая
-Запятая тоже является оператором. Ее можно вызвать явным образом, например:
+Один из самых необычных операторов -- запятая `','`.
+
+Его можно вызвать явным образом, например:
```js
//+ run
diff --git a/1-js/2-first-steps/9-comparison/article.md b/1-js/2-first-steps/8-comparison/article.md
similarity index 89%
rename from 1-js/2-first-steps/9-comparison/article.md
rename to 1-js/2-first-steps/8-comparison/article.md
index 29832001..88f4504b 100644
--- a/1-js/2-first-steps/9-comparison/article.md
+++ b/1-js/2-first-steps/8-comparison/article.md
@@ -1,20 +1,22 @@
# Операторы сравнения и логические значения
В этом разделе мы познакомимся с операторами сравнения и с логическими значениями, которые такие операторы возвращают.
+
[cut]
-Многие операторы сравнения знакомы нам со школы:
+
+Многие операторы сравнения знакомы нам из математики:
- Больше/меньше:
a > b
, a < b
.
- Больше/меньше или равно:
a >= b
, a <= b
.
- Равно `a == b`.
Для сравнения используется два символа равенства `'='`. Один символ `a = b` означал бы присваивание.
-- "Не равно". В школе он пишется как
≠
, в JavaScript -- знак равенства с восклицательным знаком перед ним !=
.
+- "Не равно". В математике он пишется как
≠
, в JavaScript -- знак равенства с восклицательным знаком перед ним !=
.
## Логические значения
-Как и другие операторы, сравнение возвращает значение. Это значение имеет специальный *логический* тип.
+Как и другие операторы, сравнение возвращает значение. Это значение имеет *логический* тип.
Существует всего два логических значения:
@@ -35,12 +37,12 @@ alert( 2 != 1 ); // true
```js
//+ run
-var a = true; // присвоили явно
-var b = 3 > 4; // false
+var a = true; // присваивать явно
+var b = 3 > 4; // или как результат сравнения
alert( b ); // false
-alert( a == b ); // (true == false) неверно, результат false
+alert( a == b ); // (true == false) неверно, выведет false
```
## Сравнение строк
@@ -141,18 +143,28 @@ alert( false == 0 ); // true, false становится 0, а true 1.
## Строгое равенство
-Обычное равенство не может отличить `0` от `false`:
+В обычном операторе `==` есть "проблема"" -- он не может отличить `0` от `false`:
```js
//+ run
-alert(0 == false); // true, так как false преобразуется к 0
+alert(0 == false); // true
```
+Та же ситуация с пустой строкой:
+
+
+```js
+//+ run
+alert('' == false); // true
+```
+
+Это естественное следствие того, что операнды разных типов преобразовались к числу. Пустая строка, как и `false`, при преобразовании к числу дают `0`.
+
Что же делать, если всё же нужно отличить `0` от `false`?
**Для проверки равенства без преобразования типов используются операторы строгого равенства `===` (тройное равно) и `!==`.**
-Они сравнивают без приведения типов. Если тип разный, то такие значения всегда неравны (строго):
+Если тип разный, то они всегда возвращают `false`:
```js
//+ run
@@ -175,7 +187,7 @@ alert(0 === false); // false, т.к. типы различны
Посмотрим забавные следствия.
-[smart header="Некорректный результат сравнения `null` с `0`"]
+### Некорректный результат сравнения null с 0
Сравним `null` с нулём:
```js
@@ -199,9 +211,8 @@ alert(null >= 0); // *!*true*/!*
В результате получается странная с точки зрения здравого смысла ситуация, которую мы видели в примере выше.
-[/smart]
+### Несравнимый undefined
-[smart header="Несравнимый `undefined`"]
Значение `undefined` вообще нельзя сравнивать:
```js
@@ -215,7 +226,7 @@ alert(undefined == 0); // false (3)
- Сравнения `(1)` и `(2)` дают `false` потому, что `undefined` при преобразовании к числу даёт `NaN`. А значение `NaN` по стандарту устроено так, что сравнения `==`, `<`, `>`, `<=`, `>=` и даже `===` с ним возвращают `false`.
- Проверка равенства `(3)` даёт `false`, потому что в стандарте явно прописано, что `undefined` равно лишь `null` и ничему другому.
-[/smart]
+
**Вывод: любые сравнения с `undefined/null`, кроме точного `===`, следует делать с осторожностью.**
diff --git a/1-js/2-first-steps/10-bitwise-operators/1-bitwise-operator-value/solution.md b/1-js/2-first-steps/9-bitwise-operators/1-bitwise-operator-value/solution.md
similarity index 100%
rename from 1-js/2-first-steps/10-bitwise-operators/1-bitwise-operator-value/solution.md
rename to 1-js/2-first-steps/9-bitwise-operators/1-bitwise-operator-value/solution.md
diff --git a/1-js/2-first-steps/10-bitwise-operators/1-bitwise-operator-value/task.md b/1-js/2-first-steps/9-bitwise-operators/1-bitwise-operator-value/task.md
similarity index 100%
rename from 1-js/2-first-steps/10-bitwise-operators/1-bitwise-operator-value/task.md
rename to 1-js/2-first-steps/9-bitwise-operators/1-bitwise-operator-value/task.md
diff --git a/1-js/2-first-steps/10-bitwise-operators/2-check-integer/solution.md b/1-js/2-first-steps/9-bitwise-operators/2-check-integer/solution.md
similarity index 100%
rename from 1-js/2-first-steps/10-bitwise-operators/2-check-integer/solution.md
rename to 1-js/2-first-steps/9-bitwise-operators/2-check-integer/solution.md
diff --git a/1-js/2-first-steps/10-bitwise-operators/2-check-integer/task.md b/1-js/2-first-steps/9-bitwise-operators/2-check-integer/task.md
similarity index 100%
rename from 1-js/2-first-steps/10-bitwise-operators/2-check-integer/task.md
rename to 1-js/2-first-steps/9-bitwise-operators/2-check-integer/task.md
diff --git a/1-js/2-first-steps/10-bitwise-operators/3-bitwise-symmetry/solution.md b/1-js/2-first-steps/9-bitwise-operators/3-bitwise-symmetry/solution.md
similarity index 100%
rename from 1-js/2-first-steps/10-bitwise-operators/3-bitwise-symmetry/solution.md
rename to 1-js/2-first-steps/9-bitwise-operators/3-bitwise-symmetry/solution.md
diff --git a/1-js/2-first-steps/10-bitwise-operators/3-bitwise-symmetry/task.md b/1-js/2-first-steps/9-bitwise-operators/3-bitwise-symmetry/task.md
similarity index 100%
rename from 1-js/2-first-steps/10-bitwise-operators/3-bitwise-symmetry/task.md
rename to 1-js/2-first-steps/9-bitwise-operators/3-bitwise-symmetry/task.md
diff --git a/1-js/2-first-steps/10-bitwise-operators/4-bit-rounding/solution.md b/1-js/2-first-steps/9-bitwise-operators/4-bit-rounding/solution.md
similarity index 100%
rename from 1-js/2-first-steps/10-bitwise-operators/4-bit-rounding/solution.md
rename to 1-js/2-first-steps/9-bitwise-operators/4-bit-rounding/solution.md
diff --git a/1-js/2-first-steps/10-bitwise-operators/4-bit-rounding/task.md b/1-js/2-first-steps/9-bitwise-operators/4-bit-rounding/task.md
similarity index 100%
rename from 1-js/2-first-steps/10-bitwise-operators/4-bit-rounding/task.md
rename to 1-js/2-first-steps/9-bitwise-operators/4-bit-rounding/task.md
diff --git a/1-js/2-first-steps/10-bitwise-operators/article.md b/1-js/2-first-steps/9-bitwise-operators/article.md
similarity index 83%
rename from 1-js/2-first-steps/10-bitwise-operators/article.md
rename to 1-js/2-first-steps/9-bitwise-operators/article.md
index f7e1e4d9..77d348a0 100644
--- a/1-js/2-first-steps/10-bitwise-operators/article.md
+++ b/1-js/2-first-steps/9-bitwise-operators/article.md
@@ -2,7 +2,7 @@
Побитовые операторы интерпретируют операнды как последовательность из 32 битов (нулей и единиц). Они производят операции, используя двоичное представление числа, и возвращают новую последовательность из 32 бит (число) в качестве результата.
-**Эта глава сложная, требует дополнительных знаний в программировании и не очень важная, вы можете пропустить её.**
+Эта глава требует дополнительных знаний в программировании и не очень важная, при первом чтении вы можете пропустить её и вернуться потом, когда захотите понять, как побитовые операторы работают.
[cut]
## Формат 32-битного целого числа со знаком [#signed-format]
@@ -31,11 +31,6 @@ a = 255;// 00000000000000000000000011111111
Обратите внимание, каждое число состоит ровно из 32-битов.
-[smart header="Младший бит слева"]
-Несмотря на то, что нам такой способ записи чисел кажется не совсем обычным, бывают языки и технологии, использующие способ записи "младший бит слева", когда биты пишутся наоборот, от меньшего разряда к большему.
-
-Именно поэтому спецификация EcmaScript явно говорит "старший бит слева".
-[/smart]
*Дополнение до двойки* -- это название способа поддержки отрицательных чисел.
@@ -117,8 +112,6 @@ a = 255;// 00000000000000000000000011111111
-## Описание работы операторов
-
Побитовые операторы работают следующим образом:
@@ -129,7 +122,33 @@ a = 255;// 00000000000000000000000011111111
Посмотрим, как работают операторы, на примерах.
-### & (Побитовое И)
+[smart header="Вспомогательные функции parseInt, toString"]
+
+Для удобной работы с примерами в этой статье, если вы захотите протестировать что-то в консоли, пригодятся две функции.
+
+
+- `parseInt("11000", 2)` -- переводит строку с двоичной записью числа в число.
+- `n.toString(2)` -- получает для числа `n` запись в 2-ной системе в виде строки.
+
+
+Например:
+
+```js
+//+ run
+var access = parseInt("11000", 2); // получаем число из строки
+
+alert(access); // 24, число с таким 2-ным представлением
+
+var access2 = access.toString(2); // обратно двоичную строку из числа
+
+alert(access2); // 11000
+```
+
+Без них перевод в двоичную систему и обратно был бы куда менее удобен.
+Более подробно они разбираются в главе [](/number).
+[/smart]
+
+## & (Побитовое И)
Выполняет операцию И над каждой парой бит.
@@ -158,7 +177,7 @@ a = 255;// 00000000000000000000000011111111
= 8 (по осн. 10)
```
-### | (Побитовое ИЛИ)
+## | (Побитовое ИЛИ)
Выполняет операцию ИЛИ над каждой парой бит. Результат `a | b` равен 1, если хотя бы один бит из a,b
равен 1.
@@ -185,7 +204,7 @@ a = 255;// 00000000000000000000000011111111
= 15 (по осн. 10)
```
-### ^ (Исключающее ИЛИ)
+## ^ (Исключающее ИЛИ)
Выполняет операцию "Исключающее ИЛИ" над каждой парой бит.
@@ -271,9 +290,7 @@ a = 255;// 00000000000000000000000011111111
[/smart]
-
-
-### ~ (Побитовое НЕ)
+## ~ (Побитовое НЕ)
Производит операцию НЕ над каждым битом, заменяя его на обратный ему.
@@ -429,14 +446,21 @@ alert( 100 >> 3 ); // 12, деление на 2 три раза, целая ча
### Маска
-Для этого примера представим, что наш скрипт работает с пользователями:
+Для этого примера представим, что наш скрипт работает с пользователями.
+
+У них могут быть различные роли в проекте:
+
- `Гость`
- `Редактор`
- `Админ`
-У каждого из них есть ряд доступов, которые можно свести в таблицу:
+Каждой роли соответствует ряд доступов к статьям и функционалу сайта.
+
+Например, `Гость` может лишь просматривать статьи сайта, а `Редактор` -- ещё и редактировать их, и тому подобное.
+
+Что-то в таком духе:
@@ -514,7 +538,11 @@ alert( 100 >> 3 ); // 12, деление на 2 три раза, целая ча
-**Мы "упаковали" много информации в одно число. Это экономит память. Но, кроме этого, по нему очень легко проверить, имеет ли посетитель заданную *комбинацию доступов*!**
+В последней колонке находится десятичное число, которое получится, если прочитать строку доступов в двоичном виде.
+
+Например, доступ гостя `10100 = 20`.
+
+Такая интерпретация доступов позволяет "упаковать" много информации в одно число. Это экономит память, а кроме этого -- это удобно, поскольку в дополнение к экономии -- по такому значению очень легко проверить, имеет ли посетитель заданную *комбинацию доступов*!
Для этого посмотрим, как в 2-ной системе представляется каждый доступ в отдельности.
@@ -526,113 +554,63 @@ alert( 100 >> 3 ); // 12, деление на 2 три раза, целая ча
- Доступ, соответствующий только просмотру статей: `10000 (=16)`.
-Например, просматривать и изменять статьи позволит доступ `access = 11000`.
+Доступ одновременно на просмотр и изменение статей -- это двоичное число с `1` на соответствующих позициях, то есть `access = 11000`.
Как правило, доступы задаются в виде констант:
```js
var ACCESS_ADMIN = 1; // 00001
-var ACCESS_GOODS_CHANGE = 2; // 00010
+var ACCESS_GOODS_EDIT = 2; // 00010
var ACCESS_GOODS_VIEW = 4; // 00100
-var ACCESS_ARTICLE_CHANGE = 8; // 01000
+var ACCESS_ARTICLE_EDIT = 8; // 01000
var ACCESS_ARTICLE_VIEW = 16; // 10000
```
Из этих констант получить нужную комбинацию доступов можно при помощи операции `|`.
```js
-var access = ACCESS_ARTICLE_VIEW | ACCESS_ARTICLE_CHANGE; // 11000
+var guest = ACCESS_ARTICLE_VIEW | ACCESS_GOODS_VIEW; // 10100
+var editor = guest | ACCESS_ARTICLE_EDIT | ACCESS_GOODS_EDIT; // 11110
+var admin = editor | ACCESS_ADMIN; // 11111
```
-### Двоичные числа в JavaScript
+Теперь, чтобы понять, есть ли в доступе `editor` нужный доступ, например управление правами -- достаточно применить к нему побитовый оператор И (`&`) с соответствующей константой.
-Для удобной работы с примерами в этой статье пригодятся две функции.
+Ненулевой результат будет означать, что доступ есть:
-
-- `parseInt("11000", 2)` -- переводит строку с двоичной записью числа в число.
-- `n.toString(2)` -- получает для числа `n` запись в 2-ной системе в виде строки.
-
-
-Например:
-
-```js
-//+ run
-var access = parseInt("11000", 2); // получаем число из строки
-
-alert(access); // 24, число с таким 2-ным представлением
-
-var access2 = access.toString(2); // обратно двоичную строку из числа
-
-alert(access2); // 11000
```
-
-### Проверка доступов
-
-Для того, чтобы понять, есть ли в доступе `access` нужный доступ, например управление правами -- достаточно применить к нему побитовый оператор И (`&`) с соответствующей маской.
-
-Создадим для примера ряд доступов и проверим их:
-
-```js
-//+ run
-var access = parseInt("11111", 2); // 31, все 1 означает, что доступ полный
-
-alert(access & ACCESS_ADMIN); // если результат не 0, то есть доступ ACCESS_ADMIN
-```
-
-А теперь та же проверка для посетителя с другими правами:
-
-```js
-//+ run
-var access = parseInt("10100"); // 20, нет 1 в конце
-
-alert(access & ACCESS_ADMIN); // 0, нет доступа к управлению правами
+alert(editor & ACCESS_ADMIN); // 0, доступа нет
+alert(editor & ACCESS_ARTICLE_EDIT); // 8, доступ есть
```
Такая проверка работает, потому что оператор И ставит `1` на те позиции результата, на которых в обоих операндах стоит `1`.
-Так что `access & 1` для любого числа `access` поставит все биты в ноль, кроме самого правого. А самый правый станет `1` только если он равен `1` в `access`.
-
-Для полноты картины также проверим, даёт ли доступ `11111` право на изменение товаров. Для этого нужно применить к доступу оператор И (`&`) с `00010` (=`2` в 10-ной системе).
-
-```js
-//+ run
-var adminAccess = 31; // 111*!*1*/!*1
-
-alert(adminAccess & ACCESS_GOODS_CHANGE); // не 0, есть доступ к изменению товаров
-```
-
**Можно проверить один из нескольких доступов.**
Например, проверим, есть ли права на просмотр ИЛИ изменение товаров. Соответствующие права задаются битом `1` на втором и третьем месте с конца, что даёт число `00110` (=`6` в 10-ной системе).
```js
-//+ run
-var check = ACCESS_GOODS_VIEW | ACCESS_GOODS_CHANGE; // 6, 00110
+var check = ACCESS_GOODS_VIEW | ACCESS_GOODS_EDIT; // 6, 00110
-var access = 30; // 11*!*11*/!*0;
-
-alert(access & check); // не 0, значит есть доступ к просмотру ИЛИ изменению
-
-access = parseInt("11100", 2);
-
-alert(access & check); // не 0, есть доступ к просмотру ИЛИ изменению
+alert(admin & check); // не 0, значит есть доступ к просмотру ИЛИ изменению
```
-Как видно из примера выше, если в аргументе `check` стоит ИЛИ из нескольких доступов `ACCESS_*`, то и результат проверки скажет, есть ли хотя бы один из них. А какой -- нужно смотреть отдельной проверкой, если это важно.
+*Битовой маской* называют как раз комбинацию двоичных значений (`check` в примере выше), которая используется для проверки и выборки единиц на нужных позициях.
-**Итак, маска даёт возможность удобно "паковать" много битовых значений в одно число при помощи ИЛИ `|`, а также, при помощи оператора И (`&`), проверять маску на комбинацию установленных битов.**
+Маски могут быть весьма удобны.
-### Маски в функциях
-
-Зачастую маски используют в функциях, чтобы одним параметром передать несколько "флагов", т.е. однобитных значений.
-
-Например:
+В частности, их используют в функциях, чтобы одним параметром передать несколько "флагов", т.е. однобитных значений.
+Пример вызова функции с маской:
```js
// найти пользователей с правами на изменение товаров или администраторов
-findUsers(ACCESS_GOODS_CHANGE | ACCESS_ADMIN);
+findUsers(ACCESS_GOODS_EDIT | ACCESS_ADMIN);
```
+Это довольно-таки коротко и элегантно, но, вместе с тем, применение масок налагает определённые ограничения. В частности, побитовые операторы в JavaScript работают только с 32-битными числами, а значит, к примеру, 33 доступа уже в число не упакуешь. Да и работа с двоичной системой счисления -- как ни крути, менее удобна, чем с десятичной или с обычными логическими значениями `true/false`.
+
+Поэтому основная сфера применения масок -- это быстрые вычисления, экономия памяти, низкоуровневые операции, связанные с рисованием из JavaScript (3d-графика), интеграция с некоторыми функциями ОС (для серверного JavaScript), и другие ситуации, когда уже существуют функции, требующие битовую маску.
+
### Округление
Так как битовые операции отбрасывают десятичную часть, то их можно использовать для округления. Достаточно взять любую операцию, которая не меняет значение числа.
@@ -667,7 +645,7 @@ alert( 1.1 + 1.2 ^ 0 ); // 2, сложение выполнится раньше
### Проверка на -1
-[Внутренний формат](#signed-format) чисел устроен так, что для смены знака нужно все биты заменить на противоположные ("обратить") и прибавить `1`.
+[Внутренний формат](#signed-format) 32-битных чисел устроен так, что для смены знака нужно все биты заменить на противоположные ("обратить") и прибавить `1`.
Обращение битов -- это побитовое НЕ (`~`). То есть, при таком формате представления числа `-n = ~n + 1`. Или, если перенести единицу: `~n = -(n+1)`.
@@ -706,7 +684,7 @@ if (~str.indexOf("верка")) { // Сочетание "if (~...indexOf)" чи
### Умножение и деление на степени 2
-Оператор `a << b`, сдвигая биты, по сути умножает `a` на 2b
.
+Оператор `a << b`, сдвигая биты, по сути умножает `a` на `2` в степени `b`.
Например:
@@ -719,7 +697,7 @@ alert( 3 << 3 ); // 3*(2*2*2) = 24
При этом следует иметь в виду, что максимальный верхний порог такого умножения меньше, чем обычно, так как побитовый оператор оперирует 32-битными целыми, в то время как обычные операторы оперируют числами длиной 64 бита.
-**Оператор `a >> b`, сдвигая биты, производит целочисленное деление `a` на 2b
.**
+Оператор сдвига в другую сторону `a >> b`, производит обратную операцию -- целочисленное деление `a` на 2b
.
```js
//+ run
@@ -736,17 +714,18 @@ alert( 11 >> 2 ); // 2, целочисленное деление (менее з
Как правило, битовое представление числа используется для:
-- Упаковки нескольких битововых значений ("флагов") в одно значение. Это экономит память и позволяет проверять наличие комбинации флагов одним оператором `&`. Кроме того, такое упакованное значение будет для функции всего одним параметром, это тоже удобно.
- Округления числа: `(12.34^0) = 12`.
- Проверки на равенство `-1`: `if (~n) { n не -1 }`.
+- Упаковки нескольких битововых значений ("флагов") в одно значение. Это экономит память и позволяет проверять наличие комбинации флагов одним оператором `&`.
+- Других ситуаций, когда нужны битовые маски.
[head]
[/head]
\ No newline at end of file
diff --git a/1-js/2-first-steps/7-properties-and-methods/article.md b/1-js/4-data-structures/1-properties-and-methods/article.md
similarity index 100%
rename from 1-js/2-first-steps/7-properties-and-methods/article.md
rename to 1-js/4-data-structures/1-properties-and-methods/article.md