diff --git a/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md b/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md index 935087ab0a..67c4f8f80d 100644 --- a/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md +++ b/1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md @@ -6,7 +6,7 @@ alert( alert(1) || 2 || alert(3) ); Вызов `alert` не возвращает значения, или, иначе говоря, возвращает `undefined`. -1. Первый оператор ИЛИ `||` выполнит первый `alert(1)`. +1. Первый оператор ИЛИ `||` вычислит свой левый операнд `alert(1)`. Это приведёт к показу первого сообщения, `1`. 2. Получит `undefined` и пойдёт дальше, ко второму операнду в поисках истинного значения. 3. Так как второй операнд `2` является истинным, то вычисления завершатся, результатом `undefined || 2` будет `2`, которое будет выведено внешним `alert( .... )`. diff --git a/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md b/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md index ffe2b32a19..18e60bb3e1 100644 --- a/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md +++ b/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md @@ -1,4 +1,4 @@ -Ответ: `null`, потому что это первое "ложное" значение из списка. +Ответ: `null`, потому что это первое ложное значение из списка. ```js run alert( 1 && null && 2 ); diff --git a/1-js/02-first-steps/11-logical-operators/4-alert-and/solution.md b/1-js/02-first-steps/11-logical-operators/4-alert-and/solution.md index f7529e616a..469b3ae113 100644 --- a/1-js/02-first-steps/11-logical-operators/4-alert-and/solution.md +++ b/1-js/02-first-steps/11-logical-operators/4-alert-and/solution.md @@ -4,7 +4,7 @@ alert( alert(1) && alert(2) ); ``` -Вызов `alert` не возвращает значения, или, иначе говоря, возвращает `undefined`. +Вызов `alert` возвращает `undefined` (он просто показывает сообщение, поэтому ничего важного не возвращает). -Поэтому до правого `alert `дело не дойдёт, вычисления закончатся на левом. +Следовательно, оператор `&&` вычисляет левый операнд (выводит `1`) и тут же останавливается, так как `undefined` является ложным значением. А `&&` как раз ищет ложное значение и возвращает его, так что его миссия выполнена. diff --git a/1-js/02-first-steps/11-logical-operators/5-alert-and-or/solution.md b/1-js/02-first-steps/11-logical-operators/5-alert-and-or/solution.md index e3bf422fa9..aca5294224 100644 --- a/1-js/02-first-steps/11-logical-operators/5-alert-and-or/solution.md +++ b/1-js/02-first-steps/11-logical-operators/5-alert-and-or/solution.md @@ -12,5 +12,5 @@ alert( null || 2 && 3 || 4 ); null || 3 || 4 ``` -Теперь результатом является первое истинное значение: `3`. +Теперь результатом является первое истинное значение: `3`. diff --git a/1-js/02-first-steps/11-logical-operators/5-alert-and-or/task.md b/1-js/02-first-steps/11-logical-operators/5-alert-and-or/task.md index 48736169e7..e402274faf 100644 --- a/1-js/02-first-steps/11-logical-operators/5-alert-and-or/task.md +++ b/1-js/02-first-steps/11-logical-operators/5-alert-and-or/task.md @@ -2,7 +2,7 @@ importance: 5 --- -# Что выведет этот код? +# Результат ИЛИ И ИЛИ? Что выведет код ниже? diff --git a/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md b/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md index 8815102f8e..d52888758e 100644 --- a/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md +++ b/1-js/02-first-steps/11-logical-operators/7-check-if-out-range/task.md @@ -4,6 +4,6 @@ importance: 3 # Проверка значения вне диапазона -Напишите условие `if` для проверки, что значение переменной `age` НЕ находится в диапазоне `14` и `90` включительно. +Напишите условие `if` для проверки, что значение переменной `age` НЕ находится в диапазоне между `14` и `90` включительно. Напишите два варианта: первый с использованием оператора НЕ `!`, второй – без этого оператора. diff --git a/1-js/02-first-steps/11-logical-operators/8-if-question/solution.md b/1-js/02-first-steps/11-logical-operators/8-if-question/solution.md index 51ccceb0b8..02c1741f11 100644 --- a/1-js/02-first-steps/11-logical-operators/8-if-question/solution.md +++ b/1-js/02-first-steps/11-logical-operators/8-if-question/solution.md @@ -1,19 +1,19 @@ -Ответ: первое и третье выполнятся. +Ответ: первый и третий выполнятся. Подробности: ```js run // Выполнится. // Результат -1 || 0 = -1, в логическом контексте true -if (-1 || 0) alert( 'first' ); +if (-1 || 0) alert( 'первый' ); // Не выполнится // -1 && 0 = 0, в логическом контексте false -if (-1 && 0) alert( 'second' ); +if (-1 && 0) alert( 'второй' ); // Выполнится -// оператор && имеет больший приоритет, чем || -// так что -1 && 1 выполнится раньше -// вычисления: null || -1 && 1 -> null || 1 -> 1 -if (null || -1 && 1) alert( 'third' ); +// Оператор && имеет больший приоритет, чем || +// так что -1 && 1 выполнится раньше, производя последовательность: +// null || -1 && 1 -> null || 1 -> 1 +if (null || -1 && 1) alert( 'третий' ); ``` diff --git a/1-js/02-first-steps/11-logical-operators/8-if-question/task.md b/1-js/02-first-steps/11-logical-operators/8-if-question/task.md index a60760e743..f9b9a07853 100644 --- a/1-js/02-first-steps/11-logical-operators/8-if-question/task.md +++ b/1-js/02-first-steps/11-logical-operators/8-if-question/task.md @@ -2,15 +2,15 @@ importance: 5 --- -# Вопрос о "if" +# Вопрос про "if" Какие из перечисленных ниже `alert` выполнятся? Какие конкретно значения будут результатами выражений в условиях `if(...)`? ```js -if (-1 || 0) alert( 'first' ); -if (-1 && 0) alert( 'second' ); -if (null || -1 && 1) alert( 'third' ); +if (-1 || 0) alert( 'первый' ); +if (-1 && 0) alert( 'второй' ); +if (null || -1 && 1) alert( 'третий' ); ``` diff --git a/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task.svg b/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task.svg index 24c222a87c..ec9ff990e1 100644 --- a/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task.svg +++ b/1-js/02-first-steps/11-logical-operators/9-check-login/ifelse_task.svg @@ -1 +1 @@ -НачалоОтмененоОтмененоЗдравствуйте!Я вас не знаюНеверный парольКто там?Пароль?ОтменаОтменаАдминЯ ГлавныйДругоеДругое \ No newline at end of file +НачалоОтмененоОтмененоЗдравствуйте!Я вас не знаюНеверный парольКто там?Пароль?ОтменаОтменаАдминЯ ГлавныйДругоеДругое \ No newline at end of file diff --git a/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md b/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md index 347bbd457d..72a99b8ab4 100644 --- a/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md +++ b/1-js/02-first-steps/11-logical-operators/9-check-login/solution.md @@ -1,24 +1,24 @@ ```js run demo -let userName = prompt("Кто там?", ''); +let userName = prompt('Кто там?', ''); -if (userName == 'Админ') { +if (userName === 'Админ') { let pass = prompt('Пароль?', ''); - if (pass == 'Я главный') { + if (pass === 'Я главный') { alert( 'Здравствуйте!' ); - } else if (pass == '' || pass == null) { + } else if (pass === '' || pass === null) { alert( 'Отменено' ); } else { alert( 'Неверный пароль' ); } -} else if (userName == '' || userName == null) { +} else if (userName === '' || userName === null) { alert( 'Отменено' ); } else { - alert( "Я вас не знаю" ); + alert( 'Я вас не знаю' ); } ``` diff --git a/1-js/02-first-steps/11-logical-operators/9-check-login/task.md b/1-js/02-first-steps/11-logical-operators/9-check-login/task.md index 76f65228ca..0b47b96657 100644 --- a/1-js/02-first-steps/11-logical-operators/9-check-login/task.md +++ b/1-js/02-first-steps/11-logical-operators/9-check-login/task.md @@ -6,13 +6,13 @@ importance: 3 Напишите код, который будет спрашивать логин с помощью `prompt`. -Если посетитель вводит "Админ", то `prompt` запрашивает пароль, если ничего не введено или нажата клавиша `key:Esc` – показать "Отменено", в противном случае отобразить "Я вас не знаю". +Если посетитель вводит `"Админ"`, то `prompt` запрашивает пароль. Если ничего не введено или нажата клавиша `key:Esc` – показать "Отменено". В других случаях отобразить "Я вас не знаю". Пароль проверять так: - Если введён пароль "Я главный", то выводить "Здравствуйте!", -- Иначе – "Неверный пароль", -- При отмене – "Отменено". +- Другая строка – "Неверный пароль", +- При пустой строке или отмене – "Отменено". Блок-схема: @@ -20,6 +20,6 @@ importance: 3 Для решения используйте вложенные блоки `if`. Обращайте внимание на стиль и читаемость кода. -Подсказка: передача пустого ввода в приглашение `prompt` возвращает пустую строку `''`. Нажатие клавиши `key:Esc` во время запроса возвращает`null`. +Подсказка: передача пустого ввода в приглашение `prompt` возвращает пустую строку `''`. Нажатие клавиши `key:Esc` во время запроса возвращает `null`. [demo] diff --git a/1-js/02-first-steps/11-logical-operators/article.md b/1-js/02-first-steps/11-logical-operators/article.md index 3337e324d5..94b2fc4463 100644 --- a/1-js/02-first-steps/11-logical-operators/article.md +++ b/1-js/02-first-steps/11-logical-operators/article.md @@ -1,6 +1,6 @@ # Логические операторы -В JavaScript есть три логических оператора: `||` (ИЛИ), `&&` (И) и `!` (НЕ). +В JavaScript есть три логических оператора: `||` (ИЛИ), `&&` (И) и `!` (НЕ). Несмотря на своё название, данные операторы могут применяться к значениям любых типов. Полученные результаты также могут иметь различный тип. @@ -14,9 +14,9 @@ result = a || b; ``` -Традиционно в программировании ИЛИ предназначено только для манипулирования булевыми значениями: в случае, если какой-либо из аргументов `true`, он вернёт `true`, в противоположной ситуации возвращается `false`. +Традиционно в программировании оператор ИЛИ предназначен только для манипулирования булевыми значениями: в случае, если какой-либо из аргументов означает `true`, возвращается `true`, в противоположной ситуации возвращается `false`. -В JavaScript, как мы увидим далее, этот оператор работает несколько иным образом. Но давайте сперва посмотрим, что происходит с булевыми значениями. +В JavaScript этот оператор сложнее и мощнее. Но давайте сперва посмотрим, что происходит с булевыми значениями. Существует всего четыре возможные логические комбинации: @@ -29,17 +29,17 @@ alert( false || false ); // false Как мы можем наблюдать, результат операций всегда равен `true`, за исключением случая, когда оба аргумента `false`. -Если значение не логического типа, то оно к нему приводится в целях вычислений. +Если значение не логического типа, то оно к нему приводится в целях вычислений. Например, число `1` будет воспринято как `true`, а `0` – как `false`: ```js run if (1 || 0) { // работает как if( true || false ) - alert( 'truthy!' ); + alert( 'истинно!' ); } ``` -Обычно оператор `||` используется в `if` для проверки истинности любого из заданных условий. +Обычно оператор `||` используется в инструкциях `if` для проверки истинности любого из заданных условий. К примеру: @@ -64,13 +64,13 @@ if (hour < 10 || hour > 18 || isWeekend) { } ``` -## ИЛИ "||" находит первое истинное значение +## ИЛИ "||" находит первое истинное значение Описанная выше логика соответствует традиционной. Теперь давайте поработаем с "дополнительными" возможностями JavaScript. Расширенный алгоритм работает следующим образом. -При выполнении ИЛИ || с несколькими значениями: +При выполнении ИЛИ `||` с несколькими значениями: ```js result = value1 || value2 || value3; @@ -84,16 +84,16 @@ result = value1 || value2 || value3; Значение возвращается в исходном виде, без преобразования. -Другими словами, цепочка ИЛИ `"||"` возвращает первое истинное значение или последнее, если такое значение не найдено. +Другими словами, цепочка ИЛИ `||` возвращает первое истинное значение или последнее, если истинного значения не найдено. Например: ```js run -alert( 1 || 0 ); // 1 -alert( true || 'no matter what' ); // true +alert( 1 || 0 ); // 1 (1 истинно) alert( null || 1 ); // 1 (первое истинное значение) alert( null || 0 || 1 ); // 1 (первое истинное значение) + alert( undefined || null || 0 ); // 0 (поскольку все ложно, возвращается последнее значение) ``` @@ -101,53 +101,40 @@ alert( undefined || null || 0 ); // 0 (поскольку все ложно, в 1. **Получение первого истинного значения из списка переменных или выражений.** - Представим, что у нас имеется ряд переменных, которые могут содержать данные или быть `null/undefined`. Как мы можем найти первую переменную с данными? + Представим, что у нас имеется ряд переменных `firstName`, `lastName` и `nickName` и все они необязательные (т.е. могут быть неопределёнными или иметь ложные значения). - С помощью `||`: + Используем ИЛИ `||`, чтобы выбрать переменную с данными и показать её значение (или строку `"Аноним"`, если все переменные пусты): ```js run - let currentUser = null; - let defaultUser = "John"; + let firstName = ""; + let lastName = ""; + let nickName = "СуперКодер"; *!* - let name = currentUser || defaultUser || "unnamed"; + alert( firstName || lastName || nickName || "Аноним"); // СуперКодер */!* - - alert( name ); // выбирается "John" – первое истинное значение ``` - Если бы и `currentUser`, и `defaultUser` были ложными, в качестве результата мы бы наблюдали `"unnamed"`. -2. **Сокращённое вычисление.** - - Операндами могут быть как отдельные значения, так и произвольные выражения. ИЛИ вычисляет их слева направо. Вычисление останавливается при достижении первого истинного значения. Этот процесс называется "сокращённым вычислением", поскольку второй операнд вычисляется только в том случае, если первого недостаточно для вычисления всего выражения. + Если бы все переменные содержали неистинные значения, было бы показано `"Аноним"`. - Это хорошо заметно, когда выражение, указанное в качестве второго аргумента, имеет побочный эффект, например, изменение переменной. - - В приведённом ниже примере `x` не изменяется: +2. **Сокращённое вычисление.** - ```js run no-beautify - let x; + Ещё одной возможностью оператора ИЛИ `||` является сокращённое вычисление. - *!*true*/!* || (x = 1); + Вот что это значит. Оператор `||` обрабатывает аргументы до первого истинного значения, после чего немедленно возвращает его, даже не приступая к вычислению дальнейших аргументов. - alert(x); // undefined, потому что (x = 1) не вычисляется - ``` + Важность такого поведения становится понятной, когда дальнейшие выражения не просто являются значениями, но имеют побочный эффект, например, изменение переменной или вызов функции. - Если бы первый аргумент имел значение `false`, то `||` приступил бы к вычислению второго и выполнил операцию присваивания: + В приведённом ниже примере будет выведено только второе сообщение: ```js run no-beautify - let x; - - *!*false*/!* || (x = 1); - - alert(x); // 1 + *!*true*/!* || alert("не выведется"); + *!*false*/!* || alert("выведется"); ``` - Присваивание - лишь один пример. Конечно, могут быть и другие побочные эффекты, которые не проявятся, если вычисление до них не дойдёт. + В первой строке оператор ИЛИ `||` прекращает вычисления сразу после того, как встретит `true`, так что `alert` не вызывается. - Как мы видим, этот вариант использования `||` является "аналогом `if`". Первый операнд преобразуется в логический. Если он оказывается ложным, начинается вычисление второго. - - В большинстве случаев лучше использовать "обычный" `if`, чтобы облегчить понимание кода, но иногда это может быть удобно. + Иногда такую конструкцию используют, чтобы выполнять команды только в случае ложности условия слева от оператора. ## && (И) @@ -173,7 +160,7 @@ let hour = 12; let minute = 30; if (hour == 12 && minute == 30) { - alert( 'The time is 12:30' ); + alert( 'Время: 12:30' ); } ``` @@ -186,7 +173,7 @@ if (1 && 0) { // вычисляется как true && false ``` -## И "&&" находит первое ложное значение +## И "&&" находит первое ложное значение При нескольких подряд операторах И: @@ -200,9 +187,9 @@ result = value1 && value2 && value3; - Каждый операнд преобразует в логическое значение. Если результат `false`, останавливается и возвращает исходное значение этого операнда. - Если все операнды были истинными, возвращается последний. -Другими словами, И возвращает первое ложное значение. Или последнее, если ничего не найдено. +Другими словами, И возвращает первое ложное значение. Или последнее, если ни одного ложного не найдено. -Вышеуказанные правила схожи с поведением ИЛИ. Разница в том, что И возвращает первое *ложное* значение, а ИЛИ -  первое *истинное*. +Вышеуказанные правила схожи с поведением ИЛИ. Разница в том, что И возвращает первое *ложное* значение, а ИЛИ -- первое *истинное*. Примеры: @@ -215,7 +202,7 @@ alert( 1 && 5 ); // 5 // Если первый операнд ложный, // И возвращает его. Второй операнд игнорируется alert( null && 5 ); // null -alert( 0 && "no matter what" ); // 0 +alert( 0 && "неважно, что тут" ); // 0 ``` Можно передать несколько значений подряд. В таком случае возвратится первое "ложное" значение, на котором остановились вычисления. @@ -231,37 +218,35 @@ alert( 1 && 2 && 3 ); // 3 ``` ````smart header="Приоритет оператора `&&` больше, чем у `||`" -Приоритет оператора И `&&` больше, чем ИЛИ `||`, так что он выполняется раньше. +Приоритет оператора И `&&` больше, чем ИЛИ `||`. Таким образом, код `a && b || c && d` по существу такой же, как если бы выражения `&&` были в круглых скобках: `(a && b) || (c && d)`. ```` -Как и оператор ИЛИ, И `&&` иногда может заменять `if`. +````warn header="Не заменяйте `if` операторами `||` или `&&`" +Иногда оператор И `&&` используют как "сокращённый вариант `if`". -К примеру: +Например: ```js run let x = 1; -(x > 0) && alert( 'Greater than zero!' ); +(x > 0) && alert( 'Больше нуля!' ); ``` -Действие в правой части `&&` выполнится только в том случае, если до него дойдут вычисления. То есть, `alert` сработает, если в левой части (`x > 0)` будет `true`. - +Действие справа от `&&` выполнится, только если вычисление до него дойдёт. То есть только если `(x > 0)` будет истинно. -Получился аналог: +Собственно, этот код аналогичен следующему: ```js run let x = 1; -if (x > 0) { - alert( 'Greater than zero!' ); -} +if (x > 0) alert( 'Больше нуля!' ); ``` -Однако, как правило, вариант с `if` лучше читается и воспринимается. +Хотя вариант с `&&` кажется более кратким, инструкция с `if` более очевидна и, как правило, более читабельна. Так что мы рекомендуем использовать каждую конструкцию по своему назначению: используйте `if`, если нужна инструкция с`if`, и используйте `&&`, если нужен оператор И. +```` -Он более очевиден, поэтому лучше использовать его. ## ! (НЕ) @@ -285,19 +270,19 @@ alert( !true ); // false alert( !0 ); // true ``` -В частности, двойное НЕ используют для преобразования значений к логическому типу: +В частности, двойное НЕ `!!` используют для преобразования значений к логическому типу: ```js run -alert( !!"non-empty string" ); // true +alert( !!"непустая строка" ); // true alert( !!null ); // false ``` То есть первое НЕ преобразует значение в логическое значение и возвращает обратное, а второе НЕ снова инвертирует его. В конце мы имеем простое преобразование значения в логическое. -Есть немного более подробный способ сделать то же самое - встроенная функция `Boolean`: +Есть чуть более длинный способ сделать то же самое — встроенная функция `Boolean`: ```js run -alert( Boolean("non-empty string") ); // true +alert( Boolean("непустая строка") ); // true alert( Boolean(null) ); // false ```