Логические операторы
Здесь мы рассмотрим первые пять, операторы ?? и ??= будут в следующей статье.
Несмотря на своё название, данные операторы могут применяться к значениям любых типов. Полученные результаты также могут иметь различный тип.
Давайте рассмотрим их подробнее.
|| (ИЛИ)
Оператор «ИЛИ» выглядит как двойной символ вертикальной черты:
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 || "Аноним"); // Суперкодер
undefined
Примитивный тип данных. Состоит из единственного значения undefined . Обозначает, что значение не определено.
Время чтения: меньше 5 мин
Открыть/закрыть навигацию по статье
- Кратко
- Пример
- Как понять
- На практике
- Николай Лопин советует
- В чём разница между null, undefined и объявленной переменной без начального значения? (let foo;)
Контрибьюторы:
Обновлено 20 декабря 2021
Кратко
Скопировать ссылку «Кратко» Скопировано
Undefined — это примитивный тип данных, состоящий из одного значения undefined . Оно используется, чтобы обозначить неизвестное или неопределённое значение.
JavaScript автоматически устанавливает значение undefined объявленным переменным, которые не были проинициализированы значением.
Пример
Скопировать ссылку «Пример» Скопировано
JavaScript автоматически устанавливает значение undefined новой переменной:
let name console.log(name)// undefinedlet name console.log(name) // undefinedТакже JavaScript автоматически устанавливает значение undefined в аргумент функции, если значение не передали при вызове:
function hello(name) console.log('Привет, ' + name)> hello('Витя')// Привет, Витяhello()// Привет, undefinedfunction hello(name) console.log('Привет, ' + name) > hello('Витя') // Привет, Витя hello() // Привет, undefinedВручную установленное undefined используют, чтобы обозначить неизвестное значение:
const person = name: 'Пётр', lastName: 'Романов', age: undefined>const person = name: 'Пётр', lastName: 'Романов', age: undefined >Но будьте аккуратны, когда устанавливаете undefined свойствам объектов. Если у объекта person удалить age , то при обращении к несуществующему свойству также вернётся undefined .
Как понять
Скопировать ссылку «Как понять» Скопировано
undefined обозначает, что значение по каким-то причинам ещё не установлено или неизвестно. В этом контексте его использует сам язык JavaScript.
В языке существует похожий примитив null . Он обозначает, что значение отсутствует. undefined и null можно легко спутать, потому что это близкие понятия. Различие состоит в том, что null обозначает отсутствие значения, а undefined — что значение неизвестно или не задано.
На практике
Скопировать ссылку «На практике» Скопировано
Николай Лопин советует
Скопировать ссылку «Николай Лопин советует» Скопировано
Разделение между undefined и null очень слабое. Это рекомендация, которую не все выполняют. Команды могут договориться о своей трактовке этих значений.
Например, в приложении нужно отобразить список пользователей, полученный с сервера. Пока данных нет, мы рисуем заглушку. В этом случае мы можем трактовать значение undefined как «отправили запрос на сервер, рисуем заглушку и ждём ответа», а null как «сервер ответил, что у него нет данных».
Уточняйте договорённости по undefined и null на проекте. Часто они не зафиксированы на бумаге, но имеют большое значение.
На собеседовании
Скопировать ссылку «На собеседовании» Скопировано
В чём разница между null , undefined и объявленной переменной без начального значения? ( let foo; )
Скопировать ссылку «В чём разница между null, undefined и объявленной переменной без начального значения? (let foo;)» Скопировано
Скопировать ссылку «Александр Рассудихин отвечает» Скопировано
null обычно задаётся переменной явно и означает, что она ничего не содержит. undefined показывает, что значение переменной «не определено». undefined обычно присваивается переменной, когда она была объявлена, но не было определено её начальное значение. Также, undefined может возвращаться и из функции — это происходит, если функции явно не возвращает ничего другого. null же обычно возвращают из функции явно, чтобы показать, что результат функции равен «ничему».
Без начального значения можно оставлять только переменную объявленную через let или var . Если объявить переменную через const и не задать ей начального значения, будет ошибка: Uncaught SyntaxError : Missing initializer in const declaration .
Оператор typeof для null работает странно. typeof ( null ) выдаст нам строку ‘object’. Это официально признанная ошибка в языке, сохраняемая для совместимости. Ошибка тут в том, что null это отдельный тип данных, а не объект. С undefined всё куда лучше и typeof ( undefined ) выдаст нам ‘undefined’. Почитать ещё о typeof можно здесь.
Поговорим немного о приведении типов. Для начала, пример:
console.log(null + null); // 0console.log(undefined + undefined); // NaNconsole.log(null + null); // 0 console.log(undefined + undefined); // NaNnull во время сложения приводится к нулю. Это логично, так как числовым значением «ничего» является как раз 0.
С undefined другое поведении, так как JavaScript пытается привести его к числу, но у него не получается и в результате мы получаем NaN .Немного упомяну и про оператор нулевого слияния ( ? ? ). В выражении между двумя операндами, он будет возвращать первый операнд, если он не равен null или undefined . Можно сказать, что ? ? приравнивает смысл undefined и null к «ничего не содержит» и в этом случае, кладёт в переменную значение второго операнда.
Синтаксис JavaScript
С 1995 года JavaScript прошел длинный путь от скромного компонента браузера Netscape до современных высокопроизводительных JIT-интерпретаторов. Казалось бы, всего лет пять назад разработчики были ошеломлены появлением Ajax, а уже сейчас сложные JavaScript-приложения достигли объемов в сотни и тысячи строк кода.
В прошлом году появилось новое поколение JavaScript-приложений, ничем не отличающихся от приложений рабочего стола, — невероятный прогресс веб-технологий. Ушли в прошлое медленно выполняемые запросы страниц при каждом взаимодействии пользователя с приложением. Движки JavaScript стали настолько мощными, что появилась возможность сохранять состояние на стороне клиента, что существенно ускорило реакцию приложения и улучшило качество его работы.
Если вы знаете другие языки программирования, вам может оказаться полезна информация, что JavaScript является высокоуровневым, динамическим, нетипизированным и интерпретируемым языком программирования, который хорошо подходит для программирования в объектно-ориентированном и функциональном стилях. Свой синтаксис JavaScript унаследовал из языка Java, свои первоклассные функции – из языка Scheme, а механизм наследования на основе прототипов – из языка Self. Но вам не требуется знать все эти языки или быть знакомыми с их терминологией для изучения JavaScript.
В этой статье мы рассмотрим базовые лексические структуры языка.
Символы
При написании программ на JavaScript используется набор символов Юникода. Юникод является надмножеством кодировок ASCII и Latin-1 и поддерживает практически все письменные языки, имеющиеся на планете. Стандарт ECMAScript 3 требует, чтобы реализации JavaScript обеспечивали поддержку стандарта Юникода версии 2.1 или выше, а стандарт ECMAScript 5 требует, чтобы реализации обеспечивали поддержку стандарта Юникода версии 3 или выше.
Чувствительность к регистру
JavaScript – это язык, чувствительный к регистру символов. Это значит, что ключевые слова, имена переменных и функций и любые другие идентификаторы языка должны всегда содержать одинаковые наборы прописных и строчных букв.
Например, ключевое слово while должно набираться как «while», а не «While » или «WHILE». Аналогично myvar, Myvar, MyVar и MYVAR – это имена четырех разных переменных. Заметим, однако, что язык разметки HTML (в отличие от XHTML) не чувствителен к регистру. Так как HTML и клиентский JavaScript тесно связаны, это различие может привести к путанице. Многие JavaScript-объекты и их свойства имеют те же имена, что и теги и атрибуты языка HTML, которые они обозначают. Однако если в HTML эти теги и атрибуты могут набираться в любом регистре, то в JavaScript они обычно должны набираться строчными буквами.
Например, атрибут onclick обработчика события чаще всего задается в HTML как onClick, однако в JavaScript-коде (или в XHTML-документе) он должен быть обозначен как onclick.
Пробелы, переводы строк и символы управления форматом
JavaScript игнорирует пробелы, которые могут присутствовать между лексемами в программе. Кроме того, JavaScript также по большей части игнорирует символы перевода строки. Поэтому пробелы и символы перевода строки могут без ограничений использоваться в исходных текстах программ для форматирования и придания им удобочитаемого внешнего вида.
Помимо обычного символа пробела ( \u0020 ) JavaScript дополнительно распознает как пробельные следующие символы: табуляция ( \u0009 ), вертикальная табуляция ( \u000B ), перевод формата ( \u000C ), неразрывный пробел ( \u00A0 ), маркер порядка следования байтов ( \uFEFF ), а также все символы Юникода, относящиеся к категории Zs.
Следующие символы распознаются интерпретаторами JavaScript как символы конца строки: перевод строки ( \u000A ), возврат каретки ( \u000D ), разделитель строк ( \u2028 ) и разделитель абзацев ( \u2029 ). Последовательность из символов возврата каретки и перевода строки интерпретируется как единственный символ завершения строки.
Символы Юникода, управляющие форматом (категория Cf), такие как RIGHT-TO-LEFT MARK ( \u200F ) и LEFT-TO-RIGHT MARK ( \u200E ), управляют визуальным представлением текста, в котором они присутствуют. Они имеют большое значение для корректного отображения текста на некоторых языках и являются допустимыми в комментариях JavaScript, строковых литералах и в литералах регулярных выражений, но не в идентификаторах (таких как имена переменных), определяемых в программах JavaScript. Исключение составляют ZERO WIDTH JOINER ( \u200D ) и ZERO WIDTH NON-JOINER ( \u200C ), которые можно использовать в идентификаторах при условии, что они не являются первыми символами идентификаторов.
Полную таблицу символов Unicode вы можете посмотреть на сайте Unicode Table.
Необязательные точки с запятой
Как и в других языках программирования, для отделения инструкций друг от друга в языке JavaScript используется точка с запятой (;). Использование точек с запятой имеет важное значение для ясного выражения намерений программиста: без этого разделителя по ошибке можно принять конец одной инструкции за начало следующей и наоборот.
Обычно в JavaScript точку с запятой между инструкциями можно не ставить, если они находятся в разных строках. (Точку с запятой можно также опустить в конце программы или если следующей лексемой в программе является закрывающая фигурная скобка >.) Многие программисты на JavaScript используют точки с запятой для явного обозначения концов инструкций, даже если в этом нет необходимости.
Взгляните на следующий фрагмент. Поскольку две инструкции находятся в разных строках, первую точку с запятой можно опустить:
a = 3 b = 5;Однако если эти инструкции записать, как показано ниже, первая точка с запятой становится обязательной:
a = 3; b = 5;Комментарии
JavaScript поддерживает два способа оформления комментариев. Любой текст между символами // и концом строки рассматривается как комментарий и игнорируется JavaScript. Любой текст между символами /* и */ также рассматривается как комментарий. Эти комментарии могут состоять из нескольких строк, но не могут быть вложенными. Следующие строки представляют собой корректные JavaScript-комментарии:
// Это однострочный комментарий. /* Это тоже комментарий */ // а это другой комментарий. /* Это еще один комментарий. Он располагается в нескольких строках. */Идентификаторы и зарезервированные слова
Идентификатор — это просто имя. В JavaScript идентификаторы выступают в качестве имен переменных и функций, а также меток некоторых циклов. Идентификаторы в JavaScript должны начинаться с буквы, с символа подчеркивания (_) или знака доллара ($) . Далее могут следовать любые буквы, цифры, символы подчеркивания или знаки доллара. (Цифра не может быть первым символом, так как тогда интерпретатору трудно будет отличать идентификаторы от чисел.) Примеры допустимых идентификаторов:
i my_variable_name v13 _myvar $strДля совместимости и простоты редактирования для составления идентификаторов обычно используются только символы ASCII и цифры. Однако JavaScript допускает возможность использования в идентификаторах букв и цифр из полного набора символов Юникода. Это позволяет программистам давать переменным имена на своих родных языках и использовать в них математические символы:
var имя = 'Александр'; var Π = 3.14;JavaScript резервирует ряд идентификаторов, которые играют роль ключевых слов самого языка. Эти ключевые слова не могут служить идентификаторами в программах. JavaScript также резервирует некоторые ключевые слова, которые в настоящее время не являются частью языка, но которые могут войти в его состав в будущих версиях. В приведенной таблице перечислены все ключевые слова по категориям:
Зарезервированные ключевые слова JavaScript
Категория Ключевые слова Базовые идентификаторы break delete function return typeof
case do if switch var
catch else in this void
continue false instanceof throw while
debugger finally new true with
default for null tryНовые ключевые слова в стандарте EcmaScript 5 class const enum export
extends import superЗарезервированные слова в строгом режиме (в обычном они доступны) implements let private public yield
interface package protected static
arguments evalКлючевые слова языка Java (зарезервированы в EcmaScript 3) abstract double goto native static
boolean enum implements package super
byte export import private synchronized
char extends int protected throws
class final interface public transient
const float long short volatileПредопределенные глобальные переменные и функции arguments encodeURI Infinity Number RegExp
Array encodeURIComponent isFinite Object String
Boolean Error isNaN parseFloat SyntaxError
Date eval JSON parseInt TypeError
decodeURI EvalError Math RangeError undefined
decodeURIComponent Function NaN ReferenceError URIErrorИмейте в виду, что конкретные реализации JavaScript могут содержать свои предопределенные глобальные переменные и функции. Кроме того, каждая конкретная платформа JavaScript (клиентская, серверная и прочие) может иметь свой собственный список глобальных свойств.
