Базовый курс JavaScript
-
1. Вступление. Подготовка к работе. console.log
-
2. Типы данных, операторы, методы и свойства
-
3. Динамическая типизация. Условия if, swith
-
4. Логические операторы. Функции
-
5. Функции declaration/expression. Область видимости
-
6. Объекты, массивы
-
7. Циклы while и for
-
8. Методы массивов
-
Практика 1.
-
10. Доступ к элементам в DOM. Доступ к элементам
-
11. Изменение документа. Практика: Галерея
-
12. Добавление событий
-
13. Всплытие и погружение. Объект события.
-
14. Объект Math. localStorage
-
15. Практика
-
16. Дата. This
-
17. Асинхронность js. Promise.
-
18. Практика
4. Логические операторы. Функции
Логические операторы
В JavaScript есть четыре логических оператора: ||
(ИЛИ), &&
(И) и !
(НЕ), ??
(Оператор нулевого слияния). Здесь мы рассмотрим первые три, оператор ??
будет в следующей статье.
Несмотря на своё название, данные операторы могут применяться к значениям любых типов. Полученные результаты также могут иметь различный тип.
Давайте рассмотрим их подробнее.
|| (ИЛИ)
Оператор «ИЛИ» выглядит как двойной символ вертикальной черты:
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( 'truthy!' );
}
Обычно оператор ||
используется в if
для проверки истинности любого из заданных условий.
К примеру:
let hour = 9;
if (hour < 10 || hour > 18) {
alert( 'Офис закрыт.' );
}
ИЛИ «||» находит первое истинное значение
Описанная выше логика соответствует традиционной. Теперь давайте поработаем с «дополнительными» возможностями JavaScript.
Расширенный алгоритм работает следующим образом.
При выполнении ИЛИ ||
с несколькими значениями:
result = value1 || value2 || value3;
Оператор ||
выполняет следующие действия:
- Вычисляет операнды слева направо.
- Каждый операнд конвертирует в логическое значение. Если результат
true
, останавливается и возвращает исходное значение этого операнда. - Если все операнды являются ложными (
false
), возвращает последний из них.
Значение возвращается в исходном виде, без преобразования.
Другими словами, цепочка ИЛИ ||
возвращает первое истинное значение или последнее, если такое значение не найдено.
Например:
alert( 1 || 0 ); // 1
alert( true || 'no matter what' ); // true
alert( null || 1 ); // 1 (первое истинное значение)
alert( null || 0 || 1 ); // 1 (первое истинное значение)
alert( undefined || null || 0 ); // 0 (поскольку все ложно, возвращается последнее значение)
&& (И)
Оператор И пишется как два амперсанда &&
:
result = a && b;
В традиционном программировании И возвращает true
, если оба аргумента истинны, а иначе – false
:
alert( true && true ); // true
alert( false && true ); // false
alert( true && false ); // false
alert( false && false ); // false
Пример с if
:
let hour = 12;
let minute = 30;
if (hour == 12 && minute == 30) {
alert( 'The time is 12:30' );
}
Как и в случае с ИЛИ, любое значение допускается в качестве операнда И:
if (1 && 0) { // вычисляется как true && false
alert( "не сработает, так как результат ложный" );
}
И «&&» находит первое ложное значение
При нескольких подряд операторах И:
result = value1 && value2 && value3;
Оператор &&
выполняет следующие действия:
- Вычисляет операнды слева направо.
- Каждый операнд преобразует в логическое значение. Если результат
false
, останавливается и возвращает исходное значение этого операнда. - Если все операнды были истинными, возвращается последний.
Функции
Зачастую нам надо повторять одно и то же действие во многих частях программы.
Например, необходимо красиво вывести сообщение при приветствии посетителя, при выходе посетителя с сайта, ещё где-нибудь.
Чтобы не повторять один и тот же код во многих местах, придуманы функции. Функции являются основными «строительными блоками» программы.
Примеры встроенных функций вы уже видели – это alert(message)
, prompt(message, default)
и confirm(question)
. Но можно создавать и свои.
Объявление функции
Для создания функций мы можем использовать объявление функции.
Пример объявления функции:
function showMessage() {
alert( 'Всем привет!' );
}
Вначале идёт ключевое слово function
, после него имя функции, затем список параметров в круглых скобках через запятую (в вышеприведённом примере он пустой) и, наконец, код функции, также называемый «телом функции», внутри фигурных скобок.
function имя(параметры) {
...тело...
}
Наша новая функция может быть вызвана по своему имени: showMessage()
.
Например:
function showMessage() {
alert( 'Всем привет!' );
}
showMessage();
showMessage();
Вызов showMessage()
выполняет код функции. Здесь мы увидим сообщение дважды.
Этот пример явно демонстрирует одно из главных предназначений функций: избавление от дублирования кода.
Если понадобится поменять сообщение или способ его вывода – достаточно изменить его в одном месте: в функции, которая его выводит.
Локальные переменные
Переменные, объявленные внутри функции, видны только внутри этой функции.
Например:
function showMessage() {
let message = "Привет, я JavaScript!"; // локальная переменная
alert( message );
}
showMessage(); // Привет, я JavaScript!
alert( message ); // <-- будет ошибка, т.к. переменная видна только внутри функции
Внешние переменные
У функции есть доступ к внешним переменным, например:
let userName = 'Вася';
function showMessage() {
let message = 'Привет, ' + userName;
alert(message);
}
showMessage(); // Привет, Вася
Функция обладает полным доступом к внешним переменным и может изменять их значение.
Например:
let userName = 'Вася';
function showMessage() {
userName = "Петя"; // (1) изменяем значение внешней переменной
let message = 'Привет, ' + userName;
alert(message);
}
alert( userName ); // Вася перед вызовом функции
showMessage();
alert( userName ); // Петя, значение внешней переменной было изменено функцией
Внешняя переменная используется, только если внутри функции нет такой локальной.
Если одноимённая переменная объявляется внутри функции, тогда она перекрывает внешнюю. Например, в коде ниже функция использует локальную переменную userName
. Внешняя будет проигнорирована:
let userName = 'Вася';
function showMessage() {
let userName = "Петя"; // объявляем локальную переменную
let message = 'Привет, ' + userName; // Петя
alert(message);
}
// функция создаст и будет использовать свою собственную локальную переменную userName
showMessage();
alert( userName ); // Вася, не изменилась, функция не трогала внешнюю переменную
Переменные, объявленные снаружи всех функций, такие как внешняя переменная userName
в вышеприведённом коде – называются глобальными.
Глобальные переменные видимы для любой функции (если только их не перекрывают одноимённые локальные переменные).
Желательно сводить использование глобальных переменных к минимуму. В современном коде обычно мало или совсем нет глобальных переменных. Хотя они иногда полезны для хранения важнейших «общепроектовых» данных.
Параметры
Мы можем передать внутрь функции любую информацию, используя параметры.
В нижеприведённом примере функции передаются два параметра: from
и text
.
function showMessage(from, text) { // параметры: from, text
alert(from + ': ' + text);
}
showMessage('Аня', 'Привет!'); // Аня: Привет! (*)
showMessage('Аня', "Как дела?"); // Аня: Как дела? (**)
Когда функция вызывается в строках (*)
и (**)
, переданные значения копируются в локальные переменные from
и text
. Затем они используются в теле функции.
Вот ещё один пример: у нас есть переменная from
, и мы передаём её функции. Обратите внимание: функция изменяет значение from
, но это изменение не видно снаружи. Функция всегда получает только копию значения:
function showMessage(from, text) {
from = '*' + from + '*'; // немного украсим "from"
alert( from + ': ' + text );
}
let from = "Аня";
showMessage(from, "Привет"); // *Аня*: Привет
// значение "from" осталось прежним, функция изменила значение локальной переменной
alert( from ); // Аня
Значение, передаваемое в качестве параметра функции, также называется аргументом.
Другими словами:
- Параметр – это переменная, указанная в круглых скобках в объявлении функции.
- Аргумент – это значение, которое передаётся функции при её вызове.
Мы объявляем функции со списком параметров, затем вызываем их, передавая аргументы.
Рассматривая приведённый выше пример, мы могли бы сказать: «функция showMessage
объявляется с двумя параметрами, затем вызывается с двумя аргументами: from
и "Привет"
«.
Значения по умолчанию
Если при вызове функции аргумент не был указан, то его значением становится undefined
.
Например, вышеупомянутая функция showMessage(from, text)
может быть вызвана с одним аргументом:
showMessage("Аня");
Это не приведёт к ошибке. Такой вызов выведет "*Аня*: undefined"
. В вызове не указан параметр text
, поэтому предполагается, что text === undefined
.
Если мы хотим задать параметру text
значение по умолчанию, мы должны указать его после =
:
function showMessage(from, text = "текст не добавлен") {
alert( from + ": " + text );
}
showMessage("Аня"); // Аня: текст не добавлен
Теперь, если параметр text
не указан, его значением будет "текст не добавлен"
В данном случае "текст не добавлен"
это строка, но на её месте могло бы быть и более сложное выражение, которое бы вычислялось и присваивалось при отсутствии параметра. Например:
function showMessage(from, text = anotherFunction()) {
// anotherFunction() выполнится только если не передан text
// результатом будет значение text
}
В JavaScript параметры по умолчанию вычисляются каждый раз, когда функция вызывается без соответствующего параметра.
В приведённом выше примере, функция anotherFunction()
не будет вызвана вообще, если указан параметр text
.
С другой стороны, функция будет независимо вызываться каждый раз, когда text
отсутствует.
Ранние версии JavaScript не поддерживали параметры по умолчанию. Поэтому существуют альтернативные способы, которые могут встречаться в старых скриптах.
Например, явная проверка на undefined
:
function showMessage(from, text) {
if (text === undefined) {
text = 'текст не добавлен';
}
alert( from + ": " + text );
}
…Или с помощью оператора ||
:
function showMessage(from, text) {
// Если значение text ложно, тогда присвоить параметру text значение по умолчанию
// заметим, что при этом пустая строка text === "" будет также считаться отсутствующим значением
text = text || 'текст не добавлен';
...
}
Альтернативные параметры по умолчанию
Иногда имеет смысл присваивать значения по умолчанию для параметров не в объявлении функции, а на более позднем этапе.
Во время выполнения функции мы можем проверить, передан ли параметр, сравнив его с undefined
:
function showMessage(text) {
// ...
if (text === undefined) { // если параметр отсутствует
text = 'пустое сообщение';
}
alert(text);
}
showMessage(); // пустое сообщение
…Или мы можем использовать оператор ||
:
function showMessage(text) {
// если значение text ложно или равняется undefined, тогда присвоить text значение 'пусто'
text = text || 'пусто';
...
}
Современные движки JavaScript поддерживают оператор нулевого слияния ??
. Его использование будет лучшей практикой, в случае, если большинство ложных значений, таких как 0
, следует расценивать как «нормальные».
function showCount(count) {
// если count равен undefined или null, показать "неизвестно"
alert(count ?? "неизвестно");
}
showCount(0); // 0
showCount(null); // неизвестно
showCount(); // неизвестно
Возврат значения
Функция может вернуть результат, который будет передан в вызвавший её код.
Простейшим примером может служить функция сложения двух чисел:
function sum(a, b) {
return a + b;
}
let result = sum(1, 2);
alert( result ); // 3
Директива return
может находиться в любом месте тела функции. Как только выполнение доходит до этого места, функция останавливается, и значение возвращается в вызвавший её код (присваивается переменной result
выше).
Вызовов return
может быть несколько, например:
function checkAge(age) {
if (age > 18) {
return true;
} else {
return confirm('А родители разрешили?');
}
}
let age = prompt('Сколько вам лет?', 18);
if ( checkAge(age) ) {
alert( 'Доступ получен' );
} else {
alert( 'Доступ закрыт' );
}
Возможно использовать return
и без значения. Это приведёт к немедленному выходу из функции.