Логические операторы
Здесь мы рассмотрим первые пять, операторы ?? и ??= будет в следующей статье.
Несмотря на своё название, данные операторы могут применяться к значениям любых типов. Полученные результаты также могут иметь различный тип.
Давайте рассмотрим их подробнее.
|| (ИЛИ)
Оператор «ИЛИ» выглядит как двойной символ вертикальной черты:
result = a || b;
Традиционно в программировании ИЛИ предназначено только для манипулирования булевыми значениями: в случае, если какой-либо из аргументов true , он вернёт true , в противоположной ситуации возвращается false .
В JavaScript, как мы увидим далее, этот оператор работает несколько иным образом. Но давайте сперва посмотрим, что происходит с булевыми значениями.
Существует всего четыре возможные логические комбинации:
alert( true || true ); // true alert( false || true ); // true alert( true || false ); // true alert( false || false ); // false
Как мы можем наблюдать, результат операций всегда равен true , за исключением случая, когда оба аргумента false .
Если значение не логического типа, то оно к нему приводится в целях вычислений.
Например, число 1 будет воспринято как true , а 0 – как false :
if (1 || 0) < // работает как if( true || false ) alert( 'истинно!' ); >
Обычно оператор || используется в if для проверки истинности любого из заданных условий.
let hour = 9; if (hour < 10 || hour >18)
Можно передать и больше условий:
let hour = 12; let isWeekend = true; if (hour < 10 || hour >18 || isWeekend) < alert( 'Офис закрыт.' ); // это выходной >
ИЛИ «||» находит первое истинное значение
Описанная выше логика соответствует традиционной. Теперь давайте поработаем с «дополнительными» возможностями JavaScript.
Расширенный алгоритм работает следующим образом.
При выполнении ИЛИ || с несколькими значениями:
result = value1 || value2 || value3;
Оператор || выполняет следующие действия:
- Вычисляет операнды слева направо.
- Каждый операнд конвертирует в логическое значение. Если результат true , останавливается и возвращает исходное значение этого операнда.
- Если все операнды являются ложными ( false ), возвращает последний из них.
Значение возвращается в исходном виде, без преобразования.
Другими словами, цепочка ИЛИ || возвращает первое истинное значение или последнее, если такое значение не найдено.
alert( 1 || 0 ); // 1 (1 - истинное значение) alert( true || 'какая-то строка' ); // true alert( null || 1 ); // 1 (первое истинное значение) alert( null || 0 || 1 ); // 1 (первое истинное значение) alert( undefined || null || 0 ); // 0 (поскольку все ложно, возвращается последнее значение)
Это делает возможным более интересное применение оператора по сравнению с «чистым, традиционным, только булевым ИЛИ».
-
Получение первого истинного значения из списка переменных или выражений. Например, у нас есть переменные firstName , lastName и nickName , все они необязательные (т.е. они могут быть неопределенными или иметь ложные значения). Давайте воспользуемся оператором ИЛИ || , чтобы выбрать ту переменную, в которой есть данные, и показать её (или «Аноним», если ни в одной переменной данных нет):
let firstName = ""; let lastName = ""; let nickName = "Суперкодер"; alert( firstName || lastName || nickName || "Аноним"); // Суперкодер
Задачи с собеседований на понимание основ

Здесь будут рассмотрены задачи JavaScript, задаваемые на реальных собеседованиях.
Желательно самостоятельно решить задачи на понимание основ языка JavaScript.
Ниже представлены условия задач. И далее их решения.
1) Какое будет выведено значение: let x = 5; console.log(x++); ?
2) Чему равно такое выражение: [ ] + false — null + true ?
3) Что выведет этот код: let y = 1; let x = y = 2; alert(x); ?
4) Чему равна сумма [ ] + 1 + 2?
5) Что выведет этот код: alert( «1»[0] )?
6) Чему равно 2 && 1 && null && 0 && undefined ?
8) Что выведет этот код: alert( null || 2 && 3 || 4 ); ?
9) a = [1, 2, 3]; b = [1, 2, 3]; Правда ли что a == b ?
10) Что выведет этот код: alert( +»Infinity» ); ?
11) Верно ли сравнение: «Ёжик» > «яблоко»?
12) Чему равно 0 || «» || 2 || undefined || true || falsе ?
1-я задача — Постфикс и Префикс
1) Какое будет выведено значение: let x = 5; console.log(x++); ?
let x = 5; console.log(x++);
Ответ 5 . Потому что постфиксная форма записи сначала возвращает старое значение. Об этом шла речь здесь.
Если снова вывести переменную в консоль, то мы увидим уже новое значение.
let x = 5; console.log(x++); console.log(x);
Или нужно было сделать так.
let x = 5; x++; console.log(x);
let x = 5; console.log(++x);
Сложение различных типов данных
Задача №2 — Сложение различных типов данных в JavaScript
Чему равно такое выражение: [ ] + false — null + true ?
Чтобы правильно решить эту задачу требуется анализ . Поэтому это задание следует выполнить поэтапно .
Математические операции : сложение и вычитание — выполняются последовательно друг за другом. О порядке выполнения операторов читайте здесь.
1-ый этап . Что дает сложение пустого массива с булевым значением [ ] + false ?
console.log([ ] + false); // 'false' console.log(typeof([ ] + false));
false
string
Результат false и это строка. Почему?
Следует запомнить, что в подобных выражениях пустой массив [ ] конвертируется в строку «» . Это уже не тип данных object , а тип данных string .
Таким образом в данном контексте запись [ ] + false (сложение массива и false) идентична записи «» + false (сложение строки и false) .
Из прошлой статьи известно, что сложение чего-либо со строкой дает строку .
Тут стоит обратить внимание и на цвет false в консоли — он белый (при темной теме браузера) или черный (при светлой теме): это говорит о строковом типе данных. В то время как булевы значения true или false в консоли имеют фиолетовый цвет .
Итак, сложение пустого массива с булевым значением дает в результате строку.
2-ой этап . Из строки нужно отнять (вычесть) null. Каков результат?
console.log([ ] + false); // 'false' console.log([ ] + false - null);
Вычитание из строки другого типа данных — это бессмысленная математическая операция. Поэтому в результате мы увидим NaN — не число.
3-ий этап . Что дает сложение NaN с булевым значением?
console.log([ ] + false); // 'false' console.log([ ] + false - null); // NaN console.log([ ] + false - null + true);
false
NaN
NaN
Сложение не числа NaN с булевым значением дает в результате NaN .
Итог. Чему равно такое выражение: [ ] + false — null + true ? Ответ NaN .
При решении этой задачи нужно понимать, как работает динамическая типизация.
И самое главное — запомнить особенность с пустым массивом (см. 1-ый этап).
Читайте также.

Практическая задача — Создание массива

Практическая задача – Удаление и добавление элементов в массив
Что выведет этот код let a 1 5 1 2 alert a
Директива let объявляет переменную с блочной областью видимости с возможностью инициализировать её значением.
Синтаксис
let var1 [= value1] [, var2 [= value2]] [, . varN [= valueN]];
Параметры
var1 , var2 , …, varN
Имя переменной. Может использоваться любой допустимый идентификатор.
Значение переменной. Любое допустимое выражение.
Описание
Директива let позволяет объявить локальную переменную с областью видимости, ограниченной текущим блоком кода . В отличие от ключевого слова var (en-US) , которое объявляет переменную глобально или локально во всей функции, независимо от области блока.
Объяснение, почему было выбрано название «let» можно найти здесь.
Правила области видимости
Областью видимости переменных, объявленных ключевым словом let , является блок, в котором они объявлены, и все его подблоки. В этом работа директива let схожа с работой директивы var . Основная разница заключается в том, что областью видимости переменной, объявленной директивой var , является вся функция, в которой она объявлена:
function varTest() var x = 1; if (true) var x = 2; // та же переменная! console.log(x); // 2 > console.log(x); // 2 > function letTest() let x = 1; if (true) let x = 2; // другая переменная console.log(x); // 2 > console.log(x); // 1 >
Чище код во вложенных функциях
let иногда делает код чище при использовании вложенных функций.
var list = document.getElementById("list"); for (let i = 1; i 5; i++) let item = document.createElement("li"); item.appendChild(document.createTextNode("Item " + i)); item.onclick = function (ev) console.log("Item " + i + " is clicked."); >; list.appendChild(item); > // чтобы получить такой же эффект с использованием 'var' // необходимо создать новый контекст // используя замыкание, чтобы сохранить значение неизменённым for (var i = 1; i 5; i++) var item = document.createElement("li"); item.appendChild(document.createTextNode("Item " + i)); (function (i) item.onclick = function (ev) console.log("Item " + i + " is clicked."); >; >)(i); list.appendChild(item); >
Пример выше будет выполнен как и ожидается, так как пять экземпляров внутренней функции (анонимной) будут ссылаться на пять разных экземпляров переменной i . Пример будет выполнен неверно, если заменить директиву let на var, или удалить переменную i из параметров вложенной функции и использовать внешнюю переменную i во внутренней функции.
На верхнем уровне скриптов и функций let, в отличии от var, не создаёт свойства на глобальном объекте . Например:
var x = "global_x"; let y = "global_y"; console.log(this.x); // 'global_x' console.log(this.y); // undefined
В выводе программы будет отображено слово «global_x» для this.x , но undefined для this.y .
Эмуляция приватных членов
При взаимодействии с конструкторами можно использовать выражение let чтобы открыть доступ к одному или нескольким приватным членам через использование замыканий:
var SomeConstructor; let privateScope = >; SomeConstructor = function SomeConstructor() this.someProperty = "foo"; privateScope.hiddenProperty = "bar"; >; SomeConstructor.prototype.showPublic = function () console.log(this.someProperty); // foo >; SomeConstructor.prototype.showPrivate = function () console.log(privateScope.hiddenProperty); // bar >; > var myInstance = new SomeConstructor(); myInstance.showPublic(); myInstance.showPrivate(); console.log(privateScope.hiddenProperty); // error
Эта техника позволяет получить только «статичное» приватное состояние — в примере выше, все экземпляры полученные из конструктора SomeConstructor будут ссылаться на одну и ту же область видимости privateScope .
Временные мёртвые зоны и ошибки при использовании let
Повторное объявление той же переменной в том же блоке или функции приведёт к выбросу исключения SyntaxError.
if (x) let foo; let foo; // SyntaxError thrown. >
В стандарте ECMAScript 2015 переменные, объявленные директивой let, переносятся в начало блока. Но если вы сошлётесь в блоке на переменную, до того как она объявлена директивой let, то это приведёт к выбросу исключения ReferenceError (en-US) , потому что переменная находится во «временной мёртвой зоне» с начала блока и до места её объявления. (В отличии от переменной, объявленной через var , которая просто будет содержать значение undefined )
function do_something() console.log(bar); // undefined console.log(foo); // ReferenceError: foo is not defined var bar = 1; let foo = 2; >
Вы можете столкнуться с ошибкой в операторах блока switch (en-US) , так как он имеет только один подблок.
switch (x) case 0: let foo; break; case 1: let foo; // Выброс SyntaxError из-за повторного объявления переменной break; >
Использование let в циклах for
Вы можете использовать ключевое слово let для привязки переменных к локальной области видимости цикла for . Разница с использованием var в заголовке цикла for , заключается в том, что переменные объявленные var , будут видны во всей функции, в которой находится этот цикл.
var i = 0; for (let i = i; i 10; i++) console.log(i); >
Правила области видимости
for (let expr1; expr2; expr3) statement;
В этом примере expr2, *expr3, statement *заключены в неявный блок, который содержит блок локальных переменных, объявленных конструкцией let expr1 . Пример приведён выше.
Примеры
let vs var
Когда let используется внутри блока, то область видимости переменной ограничивается этим блоком. Напомним, что отличие заключается в том, что областью видимости переменных, объявленных директивой var, является вся функция, в которой они были объявлены.
var a = 5; var b = 10; if (a === 5) let a = 4; // The scope is inside the if-block var b = 1; // The scope is inside the function console.log(a); // 4 console.log(b); // 1 > console.log(a); // 5 console.log(b); // 1
let в циклах
Вы можете использовать ключевое слово let для привязки переменных к локальной области видимости цикла for , вместо того что бы использовать глобальные переменные (объявленные с помощью var ).
for (let i = 0; i 10; i++) console.log(i); // 0, 1, 2, 3, 4 . 9 > console.log(i); // i is not defined
Нестандартизированные расширения let
let блок
Предупреждение: Поддержка let блоков была убрана в Gecko 44 баг 1023609.
let блок предоставляет способ, ассоциировать значения с переменными внутри области видимости этого блока, без влияния на значения переменных с теми же именами вне этого блока.
Синтаксис
let (var1 [= value1] [, var2 [= value2]] [, . , varN [= valueN]]) block;
Описание
let блок предоставляет локальную область видимости для переменных. Работа его заключается в привязке нуля или более переменных к области видимости этого блока кода, другими словами, он является блоком операторов. Отметим, что область видимости переменных, объявленных директивой var , в блоке let , будет той же самой, что и если бы эти переменные были объявлены вне блока let , иными словами областью видимости таких переменных по-прежнему является функция. Скобки в блоке let являются обязательными. Опускание их приведёт к синтаксической ошибке.
Пример
var x = 5; var y = 0; let (x = x+10, y = 12) console.log(x+y); // 27 > console.log(x + y); // 5
Правила для этого блока кода аналогичны как и для любого другого блока кода в JavaScript. Он может содержать свои локальные переменные, объявленные let .
Правила области видимости
Областью видимости переменных, объявленных директивой let , в блоке let является сам блок и все подблоки в нем, если они не содержат объявлений переменных с теми же именами.
let выражения
Предупреждение: Поддержка let выражений была убрана в Gecko 41 баг 1023609.
let выражение позволяет объявить переменные с областью видимости ограниченной одним выражением.
Синтаксис
let (var1 [= value1] [, var2 [= value2]] [, . varN [= valueN]]) expression;
Пример
Вы можете использовать let для объявления переменных, областью видимости которых является только одно выражение:
var a = 5; let(a = 6) console.log(a); // 6 console.log(a); // 5
Правила области видимости
В данном let выражении:
let (decls) expr
* expr *оборачивается в неявный блок.
Спецификации
| Specification |
|---|
| ECMAScript Language Specification # sec-let-and-const-declarations |
Поддержка браузерами
BCD tables only load in the browser
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 7 авг. 2023 г. by MDN contributors.
Your blueprint for a better internet.
MDN
Support
- Product help
- Report an issue
Our communities
Developers
- Web Technologies
- Learn Web Development
- MDN Plus
- Hacks Blog
- Website Privacy Notice
- Cookies
- Legal
- Community Participation Guidelines
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2023 by individual mozilla.org contributors. Content available under a Creative Commons license.
Автоматическое преобразование типов данных
Как вы уже знаете, строки в JavaScript следует брать в кавычки. Может быть такое, что всеми символами строки будут являться цифры:
let a = ‘123’;
В этом случае переменная a также является строкой, но с некоторым нюансом.
Суть нюанса в следующем: если над строкой с цифрами выполнить какую-либо математическую операцию — эта операция будет выполнена так, будто у нас действительно числа, а не строки:
alert(‘2’ * ‘3’); // выведет 6
В данном случае JavaScript видит, что мы пытаемся выполнить недопустимую для строк, но допустимую для чисел операцию.
Он также видит, что фактически наши строки — это числа в кавычках. Поэтому JavaScript автоматически выполняет преобразование этих строк к числам и выполняет соответствующую математическую операцию над ними.
Такое работает, если в наших строках только цифры. Если там будет хотя бы одна буква — JavaScript посчитает операцию некорректной и сделает ее результатом значение NaN :
alert(‘2’ * ‘3s’); // выведет NaN
Кроме того, автоматическое преобразование происходит, если операция математически корректна, но недопустима для строк.
Например, строки нельзя (а числа можно) умножать, делить, вычитать, поэтому во всех таких операциях будет автоматическое преобразование строк с цифрами в числа.
Однако, строки, как и числа, складываются с помощью оператора + . Это значит, что в случае сложения автоматического преобразования не будет:
let a = ‘1’ + ‘2’; alert(a); // выведет ’12’ — произошло сложение строк
Если одно из слагаемых число, а другое — строка, то всегда побеждает строка:
let a = 1 + ‘2’; alert(a); // выведет ’12’
В таких случаях JavaScript, наоборот, автоматически преобразует числа в строки и выполняет сложение строк.
Есть, однако, нюансы, когда слагаемых больше, чем два: в этом случае преобразование к определенному типу зависит от порядка выполнения операций.
В следующем примере вначале 2 и 3 сложатся как числа, а затем результат прибавится к строке ‘1’ уже как строка ‘5’ , что в итоге даст строку ’15’ :
let a = ‘1’ + (2 + 3); alert(a); // выведет ’15’
Если же убрать скобки, то все будет складываться слева направо. То есть сначала к строке ‘1’ прибавится число 2 и в результате получится строка ’12’ . Затем к этой строке прибавится число 3 и в результате получится строка ‘123’ :
let a = ‘1’ + 2 + 3; alert(a); // выведет ‘123’
А вот в следующем примере числа 2 и 3 написаны в начале, поэтому сначала они сложатся как числа, дав в результате число 5 , а затем к этому числу прибавится строка ‘1’ , дав в итоге строку ’51’ :
let a = 2 + 3 + ‘1’; alert(a); // выведет ’51’
Не запуская код, определите, что выведется на экран:
let a = ‘5’ + ‘2’; alert(a);
Не запуская код, определите, что выведется на экран:
let a = ‘5’ + 2; alert(a);
Не запуская код, определите, что выведется на экран:
let a = 5 + ‘2’; alert(a);
Не запуская код, определите, что выведется на экран:
let a = 5 + 2; alert(a);
Не запуская код, определите, что выведется на экран:
let a = ‘5’ * ‘2’; alert(a);
Не запуская код, определите, что выведется на экран:
let a = ‘5’ — ‘2’; alert(a);
Не запуская код, определите, что выведется на экран:
let a = ‘5’ / ‘2’; alert(a);
Не запуская код, определите, что выведется на экран:
let a = ‘5’ % ‘2’; alert(a);
Не запуская код, определите, что выведется на экран:
let a = ‘5s’ * ‘2’; alert(a);
Не запуская код, определите, что выведется на экран:
let a = ‘5s’ + ‘2’; alert(a);
Не запуская код, определите, что выведется на экран:
let a = (-‘5’) + (-‘2’); alert(a);
Не запуская код, определите, что выведется на экран:
let a = ‘5’ * 1 + ‘2’ * 1; alert(a);
Не запуская код, определите, что выведется на экран:
let a = ‘5’ * ‘1’ + ‘2’ * ‘1’; alert(a);
Не запуская код, определите, что выведется на экран: