Лекция
Привет, сегодня поговорим про операторы сравнения, обещаю рассказать все что знаю. Для того чтобы лучше понимать что такое операторы сравнения, логические значения, truthy, falsy , настоятельно рекомендую прочитать все из категории Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend).
null
и undefined
В этом разделе мы познакомимся с операторами сравнения и с логическими значениями, которые такие операторы возвращают.
Многие
операторы сравнения знакомы нам со школы:
a > b
, a < b
.a >= b
, a <= b
.a == b
.'='
. Один символ a = b
означал бы присваивание.≠
, в JavaScript — знак равенства с восклицательным знаком перед ним !=
.Как и другие операторы, сравнение возвращает значение. Это значение имеет специальныйлогический тип.
Существует всего два логических значения:
true
— имеет смысл «да», «верно», «истина».false
— означает «нет», «неверно», «ложь».Например:
1 |
alert( 2 > 1 ); // true, верно |
2 |
alert( 2 == 1 ); // false, неверно |
3 |
alert( 2 != 1 ); // true |
Логические значения можно использовать и напрямую, присваивать переменным, работать с ними как с любыми другими:
1 |
var a = true ; // присвоили явно |
2 |
var b = 3 > 4; // false |
3 |
4 |
alert( b ); // false |
5 |
6 |
alert( a == b ); // (true == false) неверно, результат false |
Строки сравниваются побуквенно:
1 |
alert( 'Б' > 'А' ); // true |
Буквы сравниваются в алфавитном порядке. Какая буква в алфавите позже — та и больше.
Аналогом «алфавита» во внутреннем представлении строк служит кодировка, у каждого символа — свой номер (код). JavaScript использует кодировку Unicode. При этом сравниваются численные коды символов.
В кодировке Unicode обычно код у строчной буквы больше, чем у прописной, поэтому:
1 |
alert( 'а' > 'Я' ); // true, строчные буквы больше прописных |
Для корректного сравнения символы должны быть в одинаковом регистре.
Сравнение осуществляется как в телефонной книжке или в словаре. Об этом говорит сайт https://intellect.icu . Сначала сравниваются первые буквы, потом вторые, и так далее, пока одна не будет больше другой.
Иными словами, больше — та строка, которая в телефонной книге была бы на большей странице.
Например:
1 |
alert( 'Банан' > 'Аят' ); |
1 |
alert( 'Вася' > 'Ваня' ); // true, т.к. 'с' > 'н' |
1 |
alert( 'Привет' > 'Прив' ); // true, так как 'е' больше чем "ничего". |
Такое сравнение называется лексикографическим.
Обычно мы получаем значения от посетителя в виде строк. Например, prompt
возвращает строку, которую ввел посетитель.
Числа, полученные таким образом, в виде строк сравнивать нельзя, результат будет неверен. Например:
1 |
alert( "2" > "14" ); // true, неверно, ведь 2 не больше 14 |
В примере выше 2
оказалось больше 14
, потому что строки сравниваются посимвольно, а первый символ '2'
больше '1'
.
Правильно было бы преобразовать их к числу явным образом. Например, поставив перед ними +
:
1 |
alert( + "2" > + "14" ); // false, теперь правильно |
При сравнении значения преобразуются к числам. Исключение: когда оба значения — строки, тогда не преобразуются.
Например:
1 |
alert( '2' > 1 ); // true |
2 |
alert( '01' == 1 ); //true |
3 |
alert( false == 0 ); // true, false становится 0, а true 1. |
Тема преобразований типов будет продолжена далее, в главе Преобразование объектов: toString и valueOf.
Обычное равенство не может отличить 0
от false
:
1 |
alert(0 == false ); // true, т.к. false преобразуется к 0 |
Что же делать, если все же нужно отличить 0
от false
?
Для проверки равенства без преобразования типов используются операторы строгого равенства ===
(тройное равно) и !==
.
Они сравнивают без приведения типов. Если тип разный, то такие значения всегда неравны (строго):
1 |
alert(0 === false ); // false, т.к. типы различны |
null
и undefined
Проблемы со специальными значениями возможны, когда к переменной применяется операция сравнения > < <= >=
, а у нее может быть как численное значение, так и null/undefined
.
Интуитивно кажется, что null/undefined
эквивалентны нулю, но это не так! Они ведут себя по-другому.
null
и undefined
равны ==
друг другу и не равны чему бы то ни было еще.null
становится 0
, а undefined
становится NaN
.Посмотрим забавные следствия.
null
с 0
Сравним null
с нулем:
1 |
alert( null > 0); // false |
2 |
alert( null == 0); // false |
Итак, мы получили, что null
не больше и не равен нулю. А теперь…
1 |
alert( null >= 0); // true |
Как такое возможно? Если нечто «больше или равно нулю», то резонно полагать, что оно либо больше, либо равно. Но здесь это не так.
Дело в том, что алгоритмы проверки равенства ==
и сравнения >= > < <=
работают по-разному.
Сравнение честно приводит к числу, получается ноль. А при проверке равенства значения null
и undefined
обрабатываются особым образом: они равны друг другу, но не равны чему-то еще.
В результате получается странная с точки зрения здравого смысла ситуация, которую мы видели в примере выше.
undefined
Значение undefined
вообще нельзя сравнивать:
1 |
alert( undefined > 0); // false (1) |
2 |
alert( undefined < 0); // false (2) |
3 |
alert( undefined == 0); // false (3) |
(1)
и (2)
дают false
потому, что undefined
при преобразовании к числу дает NaN
. А значение NaN
по стандарту устроено так, что сравнения ==
, <
,>
, <=
, >=
и даже ===
с ним возвращают false
.(3)
дает false
, потому что в стандарте явно прописано, что undefined
равно лишь null
и ничему другому.
Вывод: любые сравнения с undefined/null
, кроме точного ===
, следует делать с осторожностью. Желательно не использовать сравнения >= > < <=
, во избежание ошибок в коде.
Иногда требуется проверить, есть ли в переменной какое-либо значение. При этом важно учитывать и null
, и undefined
, и другие falsy-значения (NaN
, пустая строка, 0).
if (test1 !== null || test1 !== undefined || test1 !== '') {
// logic
}
К счастью, нет необходимости проводить все проверки по отдельности, тем более, что при этом легко что-нибудь упустить. Например, 0, который в ряде ситуаций тоже может расцениваться как "пустое" значение.
Можно просто положиться на JavaScript и его динамическую конверсию типов.
if (test1) {
// logic
}
Оператор if
самостоятельно приведет переменную к логическому значению и осуществит проверку.
true
(истина) и false
(ложь). Операторы сравнения возвращают их.===
(!==
).null
и undefined
равны ==
друг другу и не равны ничему другому. В других сравнениях (с участием >
,<
) их лучше не использовать, так как они ведут себя не как 0
.
Комментарии
Оставить комментарий
Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)
Термины: Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)