From 223dd884aea26f1d6c51f86276f5e150d013538e Mon Sep 17 00:00:00 2001 From: Ilya Kantor Date: Fri, 9 Jan 2015 01:39:01 +0300 Subject: [PATCH] renovations --- .../1-simple-page/solution.md | 0 .../1-simple-page/task.md | 0 .../{11-uibasic => 10-uibasic}/article.md | 4 +- .../1-if-zero-string/solution.md | 0 .../1-if-zero-string/task.md | 0 .../2-check-standard/ifelse_task2.png | Bin .../2-check-standard/ifelse_task2/index.html | 0 .../2-check-standard/solution.md | 0 .../2-check-standard/task.md | 0 .../2-check-standardifelse_task2/index.html | 0 .../3-sign/if_sign/index.html | 0 .../3-sign/solution.md | 0 .../{12-ifelse => 11-ifelse}/3-sign/task.md | 0 .../4-check-login/ifelse_task.png | Bin .../4-check-login/solution.md | 0 .../4-check-login/task.md | 0 .../5-rewrite-if-question/solution.md | 0 .../5-rewrite-if-question/task.md | 0 .../6-rewrite-if-else-question/solution.md | 0 .../6-rewrite-if-else-question/task.md | 0 .../{12-ifelse => 11-ifelse}/article.md | 62 ++-- .../1-alert-null-2-undefined/solution.md | 0 .../1-alert-null-2-undefined/task.md | 0 .../2-alert-or/solution.md | 0 .../2-alert-or/task.md | 0 .../3-alert-1-null-2/solution.md | 0 .../3-alert-1-null-2/task.md | 0 .../4-alert-and/solution.md | 0 .../4-alert-and/task.md | 0 .../5-check-if-in-range/solution.md | 0 .../5-check-if-in-range/task.md | 0 .../6-check-if-out-range/solution.md | 0 .../6-check-if-out-range/task.md | 0 .../7-if-question/solution.md | 0 .../7-if-question/task.md | 0 .../article.md | 46 ++- .../solution.md | 0 .../1-primitive-conversions-questions/task.md | 0 .../article.md | 46 ++- .../1-loop-last-value/solution.md | 0 .../1-loop-last-value/task.md | 0 .../2-which-value-while/solution.md | 0 .../2-which-value-while/task.md | 0 .../3-which-value-for/solution.md | 0 .../3-which-value-for/task.md | 0 .../4-for-even/solution.md | 0 .../4-for-even/task.md | 0 .../5-replace-for-while/solution.md | 0 .../5-replace-for-while/task.md | 0 .../6-repeat-until-correct/solution.md | 0 .../6-repeat-until-correct/task.md | 2 +- .../7-list-primes}/solution.md | 0 .../7-list-primes}/task.md | 2 +- 1-js/2-first-steps/14-while-for/article.md | 346 ++++++++++++++++++ .../1-rewrite-switch-if-else/solution.md | 0 .../1-rewrite-switch-if-else/task.md | 0 .../2-rewrite-if-switch/solution.md | 0 .../2-rewrite-if-switch/task.md | 0 .../{17-switch => 15-switch}/article.md | 0 1-js/2-first-steps/15-while-for/article.md | 179 --------- .../16-break-continue/article.md | 198 ---------- .../1-if-else-required/solution.md | 0 .../1-if-else-required/task.md | 0 .../solution.md | 0 .../2-rewrite-function-question-or/task.md | 0 .../3-min/solution.md | 0 .../3-min/task.md | 0 .../4-pow/solution.md | 0 .../4-pow/task.md | 0 .../article.md | 0 .../style.png | Bin .../1-sum-to/solution.md | 0 .../1-sum-to/task.md | 0 .../2-factorial/solution.md | 0 .../2-factorial/task.md | 0 .../3-fibonacci-numbers/solution.md | 0 .../3-fibonacci-numbers/task.md | 0 .../{19-recursion => 17-recursion}/article.md | 0 .../article.md | 0 .../1-nfe-check/solution.md | 0 .../1-nfe-check/task.md | 0 .../article.md | 0 .../article.md | 0 1-js/2-first-steps/6-types-intro/article.md | 6 +- .../1-increment-order/solution.md | 0 .../1-increment-order/task.md | 0 .../2-assignment-result/solution.md | 0 .../2-assignment-result/task.md | 0 .../{8-operators => 7-operators}/article.md | 201 +++++----- .../{9-comparison => 8-comparison}/article.md | 37 +- .../1-bitwise-operator-value/solution.md | 0 .../1-bitwise-operator-value/task.md | 0 .../2-check-integer/solution.md | 0 .../2-check-integer/task.md | 0 .../3-bitwise-symmetry/solution.md | 0 .../3-bitwise-symmetry/task.md | 0 .../4-bit-rounding/solution.md | 0 .../4-bit-rounding/task.md | 0 .../article.md | 167 ++++----- .../1-properties-and-methods}/article.md | 0 100 files changed, 638 insertions(+), 658 deletions(-) rename 1-js/2-first-steps/{11-uibasic => 10-uibasic}/1-simple-page/solution.md (100%) rename 1-js/2-first-steps/{11-uibasic => 10-uibasic}/1-simple-page/task.md (100%) rename 1-js/2-first-steps/{11-uibasic => 10-uibasic}/article.md (91%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/1-if-zero-string/solution.md (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/1-if-zero-string/task.md (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/2-check-standard/ifelse_task2.png (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/2-check-standard/ifelse_task2/index.html (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/2-check-standard/solution.md (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/2-check-standard/task.md (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/2-check-standardifelse_task2/index.html (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/3-sign/if_sign/index.html (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/3-sign/solution.md (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/3-sign/task.md (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/4-check-login/ifelse_task.png (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/4-check-login/solution.md (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/4-check-login/task.md (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/5-rewrite-if-question/solution.md (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/5-rewrite-if-question/task.md (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/6-rewrite-if-else-question/solution.md (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/6-rewrite-if-else-question/task.md (100%) rename 1-js/2-first-steps/{12-ifelse => 11-ifelse}/article.md (68%) rename 1-js/2-first-steps/{13-logical-ops => 12-logical-ops}/1-alert-null-2-undefined/solution.md (100%) rename 1-js/2-first-steps/{13-logical-ops => 12-logical-ops}/1-alert-null-2-undefined/task.md (100%) rename 1-js/2-first-steps/{13-logical-ops => 12-logical-ops}/2-alert-or/solution.md (100%) rename 1-js/2-first-steps/{13-logical-ops => 12-logical-ops}/2-alert-or/task.md (100%) rename 1-js/2-first-steps/{13-logical-ops => 12-logical-ops}/3-alert-1-null-2/solution.md (100%) rename 1-js/2-first-steps/{13-logical-ops => 12-logical-ops}/3-alert-1-null-2/task.md (100%) rename 1-js/2-first-steps/{13-logical-ops => 12-logical-ops}/4-alert-and/solution.md (100%) rename 1-js/2-first-steps/{13-logical-ops => 12-logical-ops}/4-alert-and/task.md (100%) rename 1-js/2-first-steps/{13-logical-ops => 12-logical-ops}/5-check-if-in-range/solution.md (100%) rename 1-js/2-first-steps/{13-logical-ops => 12-logical-ops}/5-check-if-in-range/task.md (100%) rename 1-js/2-first-steps/{13-logical-ops => 12-logical-ops}/6-check-if-out-range/solution.md (100%) rename 1-js/2-first-steps/{13-logical-ops => 12-logical-ops}/6-check-if-out-range/task.md (100%) rename 1-js/2-first-steps/{13-logical-ops => 12-logical-ops}/7-if-question/solution.md (100%) rename 1-js/2-first-steps/{13-logical-ops => 12-logical-ops}/7-if-question/task.md (100%) rename 1-js/2-first-steps/{13-logical-ops => 12-logical-ops}/article.md (73%) rename 1-js/2-first-steps/{14-types-conversion => 13-types-conversion}/1-primitive-conversions-questions/solution.md (100%) rename 1-js/2-first-steps/{14-types-conversion => 13-types-conversion}/1-primitive-conversions-questions/task.md (100%) rename 1-js/2-first-steps/{14-types-conversion => 13-types-conversion}/article.md (79%) rename 1-js/2-first-steps/{15-while-for => 14-while-for}/1-loop-last-value/solution.md (100%) rename 1-js/2-first-steps/{15-while-for => 14-while-for}/1-loop-last-value/task.md (100%) rename 1-js/2-first-steps/{15-while-for => 14-while-for}/2-which-value-while/solution.md (100%) rename 1-js/2-first-steps/{15-while-for => 14-while-for}/2-which-value-while/task.md (100%) rename 1-js/2-first-steps/{15-while-for => 14-while-for}/3-which-value-for/solution.md (100%) rename 1-js/2-first-steps/{15-while-for => 14-while-for}/3-which-value-for/task.md (100%) rename 1-js/2-first-steps/{15-while-for => 14-while-for}/4-for-even/solution.md (100%) rename 1-js/2-first-steps/{15-while-for => 14-while-for}/4-for-even/task.md (100%) rename 1-js/2-first-steps/{15-while-for => 14-while-for}/5-replace-for-while/solution.md (100%) rename 1-js/2-first-steps/{15-while-for => 14-while-for}/5-replace-for-while/task.md (100%) rename 1-js/2-first-steps/{15-while-for => 14-while-for}/6-repeat-until-correct/solution.md (100%) rename 1-js/2-first-steps/{15-while-for => 14-while-for}/6-repeat-until-correct/task.md (78%) rename 1-js/2-first-steps/{16-break-continue/1-list-primes => 14-while-for/7-list-primes}/solution.md (100%) rename 1-js/2-first-steps/{16-break-continue/1-list-primes => 14-while-for/7-list-primes}/task.md (97%) create mode 100644 1-js/2-first-steps/14-while-for/article.md rename 1-js/2-first-steps/{17-switch => 15-switch}/1-rewrite-switch-if-else/solution.md (100%) rename 1-js/2-first-steps/{17-switch => 15-switch}/1-rewrite-switch-if-else/task.md (100%) rename 1-js/2-first-steps/{17-switch => 15-switch}/2-rewrite-if-switch/solution.md (100%) rename 1-js/2-first-steps/{17-switch => 15-switch}/2-rewrite-if-switch/task.md (100%) rename 1-js/2-first-steps/{17-switch => 15-switch}/article.md (100%) delete mode 100644 1-js/2-first-steps/15-while-for/article.md delete mode 100644 1-js/2-first-steps/16-break-continue/article.md rename 1-js/2-first-steps/{18-function-basics => 16-function-basics}/1-if-else-required/solution.md (100%) rename 1-js/2-first-steps/{18-function-basics => 16-function-basics}/1-if-else-required/task.md (100%) rename 1-js/2-first-steps/{18-function-basics => 16-function-basics}/2-rewrite-function-question-or/solution.md (100%) rename 1-js/2-first-steps/{18-function-basics => 16-function-basics}/2-rewrite-function-question-or/task.md (100%) rename 1-js/2-first-steps/{18-function-basics => 16-function-basics}/3-min/solution.md (100%) rename 1-js/2-first-steps/{18-function-basics => 16-function-basics}/3-min/task.md (100%) rename 1-js/2-first-steps/{18-function-basics => 16-function-basics}/4-pow/solution.md (100%) rename 1-js/2-first-steps/{18-function-basics => 16-function-basics}/4-pow/task.md (100%) rename 1-js/2-first-steps/{18-function-basics => 16-function-basics}/article.md (100%) rename 1-js/2-first-steps/{18-function-basics => 16-function-basics}/style.png (100%) rename 1-js/2-first-steps/{19-recursion => 17-recursion}/1-sum-to/solution.md (100%) rename 1-js/2-first-steps/{19-recursion => 17-recursion}/1-sum-to/task.md (100%) rename 1-js/2-first-steps/{19-recursion => 17-recursion}/2-factorial/solution.md (100%) rename 1-js/2-first-steps/{19-recursion => 17-recursion}/2-factorial/task.md (100%) rename 1-js/2-first-steps/{19-recursion => 17-recursion}/3-fibonacci-numbers/solution.md (100%) rename 1-js/2-first-steps/{19-recursion => 17-recursion}/3-fibonacci-numbers/task.md (100%) rename 1-js/2-first-steps/{19-recursion => 17-recursion}/article.md (100%) rename 1-js/2-first-steps/{20-function-declaration-expression => 18-function-declaration-expression}/article.md (100%) rename 1-js/2-first-steps/{21-named-function-expression => 19-named-function-expression}/1-nfe-check/solution.md (100%) rename 1-js/2-first-steps/{21-named-function-expression => 19-named-function-expression}/1-nfe-check/task.md (100%) rename 1-js/2-first-steps/{21-named-function-expression => 19-named-function-expression}/article.md (100%) rename 1-js/2-first-steps/{22-javascript-specials => 20-javascript-specials}/article.md (100%) rename 1-js/2-first-steps/{8-operators => 7-operators}/1-increment-order/solution.md (100%) rename 1-js/2-first-steps/{8-operators => 7-operators}/1-increment-order/task.md (100%) rename 1-js/2-first-steps/{8-operators => 7-operators}/2-assignment-result/solution.md (100%) rename 1-js/2-first-steps/{8-operators => 7-operators}/2-assignment-result/task.md (100%) rename 1-js/2-first-steps/{8-operators => 7-operators}/article.md (72%) rename 1-js/2-first-steps/{9-comparison => 8-comparison}/article.md (89%) rename 1-js/2-first-steps/{10-bitwise-operators => 9-bitwise-operators}/1-bitwise-operator-value/solution.md (100%) rename 1-js/2-first-steps/{10-bitwise-operators => 9-bitwise-operators}/1-bitwise-operator-value/task.md (100%) rename 1-js/2-first-steps/{10-bitwise-operators => 9-bitwise-operators}/2-check-integer/solution.md (100%) rename 1-js/2-first-steps/{10-bitwise-operators => 9-bitwise-operators}/2-check-integer/task.md (100%) rename 1-js/2-first-steps/{10-bitwise-operators => 9-bitwise-operators}/3-bitwise-symmetry/solution.md (100%) rename 1-js/2-first-steps/{10-bitwise-operators => 9-bitwise-operators}/3-bitwise-symmetry/task.md (100%) rename 1-js/2-first-steps/{10-bitwise-operators => 9-bitwise-operators}/4-bit-rounding/solution.md (100%) rename 1-js/2-first-steps/{10-bitwise-operators => 9-bitwise-operators}/4-bit-rounding/task.md (100%) rename 1-js/2-first-steps/{10-bitwise-operators => 9-bitwise-operators}/article.md (83%) rename 1-js/{2-first-steps/7-properties-and-methods => 4-data-structures/1-properties-and-methods}/article.md (100%) 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`.** +В логическом контексте: + Например, такое условие никогда не выполнится: @@ -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 есть три преобразования:
      -
    1. Строковое: `String(value)` -- в строковом контексте или при сложении со строкой
    2. -
    3. Численное: `Number(value)` -- в численном контексте, включая унарный плюс `+value`.
    4. +
    5. Строковое: `String(value)` -- в строковом контексте или при сложении со строкой. Работает очевидным образом.
    6. +
    7. Численное: `Number(value)` -- в численном контексте, включая унарный плюс `+value`. Происходит при сравнении разных типов, кроме строгого равенства.
    8. Логическое: `Boolean(value)` -- в логическом контексте, можно также сделать двойным НЕ: `!!value`.
    -**Сравнение не осуществляет преобразование типов в следующих случаях:** - +Точные таблицы преобразований даны выше в этой главе. + +Особым случаем является проверка равенства с `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); +} +``` + +Здесь: + + +Цикл выполняется так: + +
      +
    1. Начало: `i=0` выполняется один-единственный раз, при заходе в цикл.
    2. +
    3. Условие: `i<3` проверяется перед каждой итерацией и при входе в цикл, если оно нарушено, то происходит выход.
    4. +
    5. Тело: `alert(i)`.
    6. +
    7. Шаг: `i++` выполняется после *тела* на каждой итерации, но перед проверкой условия.
    8. +
    9. Идти на шаг 2.
    10. +
    + +Иными, словами, поток выполнения: `начало` -> (если `условие` -> `тело` -> `шаг`) -> (если `условие` -> `тело` -> `шаг`) -> ... и так далее, пока верно `условие`. + +[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(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); -} -``` - -Здесь: - - -Цикл выполняется так: - -
      -
    1. Начало: `i=0` выполняется один-единственный раз, при заходе в цикл.
    2. -
    3. Условие: `i<3` проверяется перед каждой итерацией и при входе в цикл, если оно нарушено, то происходит выход.
    4. -
    5. Тело: `alert(i)`.
    6. -
    7. Шаг: `i++` выполняется после *тела* на каждой итерации, но перед проверкой условия.
    8. -
    9. Идти на шаг 2.
    10. -
    - -Иными, словами, поток выполнения: `начало` -> (если `условие` -> `тело` -> `шаг`) -> (если `условие` -> `тело` -> `шаг`) -> ... и так далее, пока верно `условие`. - -[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] ## Термины: "унарный", "бинарный", "операнд" У операторов есть своя терминология, которая используется во всех языках программирования. + +Прежде, чем мы двинемся дальше -- несколько терминов, чтобы понимать, о чём речь. + -Некоторые операторы, например, вычитание `"-"` и сложение `"+"`, бывают в двух вариантах: унарный -- при применении к одному операнду, и бинарный -- к двум. -## Арифметические операторы +## Сложение строк, бинарный + -Базовые арифметические операторы знакомы нам с детства: это плюс `+`, минус `-`, умножить `*`, поделить `/`. +Обычно при помощи плюса `'+'` складывают числа. -Например: - -```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] -Многие операторы сравнения знакомы нам со школы: + +Многие операторы сравнения знакомы нам из математики: ## Логические значения -Как и другие операторы, сравнение возвращает значение. Это значение имеет специальный *логический* тип. +Как и другие операторы, сравнение возвращает значение. Это значение имеет *логический* тип. Существует всего два логических значения: -[/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 три раза, целая ча
    1. Доступ, соответствующий только просмотру статей: `10000 (=16)`.
    2. -Например, просматривать и изменять статьи позволит доступ `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