Basics
Истина и ложь
Особый список "ложных" значений в JavaScript таков:
""
(пустая строка)0
,-0
,NaN
(некорректноечисло
)null
,undefined
false
Любое значение, не входящее в этот "ложный" список — "истинно." Вот несколько примеров:
"hello"
42
true
[ ]
,[ 1, "2", 3 ]
(массивы){ }
,{ a: 42 }
(объекты)function foo() { .. }
(функции)
Важно помнить, что не boolean
значение следует такому приведению ("истинный"/"ложный") только, если оно действительно приводится кboolean
. Это не единственная трудность, которая может смутить вас в ситуации, когда кажется, что есть приведение значения кboolean
, когда на самом деле его нет.
Равенство
Есть четыре операции равенства:==
,===
,!=
и!==
. Формы с!
— конечно же, симметричные версии "не равно" своих противоположностей; не равно не следует путать с неравенством.
Разница между==
и===
обычно состоит в том, что==
проверяет на равенство значений, а===
проверяет на равенство и значений, и типов. Однако это не точно. Подходящий способ охарактеризовать их:==
проверяет на равенство значений с использованием приведения, а===
проверяет на равенство не разрешая приведение. Операцию===
часто называют "строгое равенство" по этой причине.
Пример неявного приведения, которое допускается нестрогим равенством==
и не допускается строгим равенством===
:
В сравненииa == b
JS замечает, что типы не совпадают, поэтому он делает системный ряд шагов, чтобы привести одно или оба значения к различным типам, пока типы не совпадут, а затем уже может быть проверено простое равенство значений.
Если подумать, то есть два возможных пути, когдаa == b
может статьtrue
через приведение. Либо сравнение может закончиться на42 == 42
, либо на"42" == "42"
. Так какое же из них?
Ответ:"42"
становится42
, чтобы сделать сравнение42 == 42
. В таком простом примере не так уж важно, по какому пути пойдет сравнение: в конце результат будет один и тот же. Есть более сложные случаи, где важно не только, каков конечный результат сравнения, но и как вы к нему пришли.
Сравнениеa === b
дастfalse
, так как приведение не разрешено, поэтому простое сравнение значений, очевидно, не завершится успехом. Многие разработчики чувствуют, что операция===
более предсказуема, поэтому они советуют всегда использовать эту форму и держаться подальше от==
. Думаю, такая точка зрения очень недальновидна.
Чтобы свести целое множество деталей к нескольким простым мыслям и помочь вам узнать, использовать ли==
или===
в различных ситуациях:
Если одно из значений (т.е. сторона) в сравнении может быть значением:
true
илиfalse
, избегайте==
и используйте===
.Если одно из значений в сравнении может быть одним из этих особых значений (
0
,""
или[]
— пустой массив), избегайте==
и используйте===
.Во всех остальных случаях, вы можете безопасно использовать
==
. Это не только безопасно, но во многих случаях упрощает ваш код путем повышения читаемости.
Эти правила сводятся к тому, что требуют от вас критически оценивать свой код и думать о том, какого вида значения могут исходить из переменных, которые проверяются на равенство. Если вы уверенны насчет значений: == -
безопасна, то используйте ее! Если вы не уверенны насчет значений, используйте===
.
Форма неравно!=
идет в паре с==
, а форма!==
— в паре с===
. Все правила и утверждения, которые мы только что обсудили, также применимы для этих сравнений на неравно.
Следует особо обратить внимание на правила сравнения==
и===
, особенно, если вы сравниваете два непримитивных значения, таких какobject
(включаяfunction
иarray
). Так как эти значения, на самом деле, хранятся по ссылке, оба сравнения==
и===
просто проверят, равны ли ссылки, но ничего не сделают касаемо самих значений.
Например,массив
по умолчанию приводится кстроке
простым присоединением всех значений с запятыми (,
) между ними. Можно было бы подумать, что эти двамассива
с одинаковым содержимым будут равны по==
, но это не так:
Неравенство
Операции<
,>
,<=
и>=
, использующиеся для неравенств, упоминаются в спецификации как "относительное сравнение." Обычно они используются со значениями, сравниваемыми порядками, какчисла
. Легко понять, что3 < 4
.
Ностроковые
значения в JavaScript тоже могут участвовать в неравенствах, используя типичные алфавитные правила ("bar" <"foo"
).
Как насчет приведения? Тут все похоже на правила в сравнении==
(хотя и не совсем идентично!). Примечательно, что нет операций "строгого неравенства", которые бы запрещали приведение таким же путем, как и "строгое равенство"===
. Пример:
Если оба значения в сравнении<
являютсястроками
, как это было в случае сb < c
, сравнение производится лексикографически (т.е. в алфавитном порядке, как в словаре). Но если одно или оба значения не являютсястрокой
, как в случае сa < b
, то оба значения приводятся кчислу
и происходит типичное числовое сравнение.
Самое большое затруднение, которое вы можете испытать со сравнениями между потенциально разными типами значений (помните, что нет формы "строгого неравенства"?) — это когда одно из значений не может быть превращено в корректное число, например:
Так как значениеb
приводится к "некорректному числовому значению"NaN
в сравнениях<
и>
, а спецификация говорит, чтоNaN
не больше и не меньше, чем любое другое значение. Сравнение==
не проходит по другой причине. a == b
может быть некорректным, если оно интерпретируется как 42 == NaN
или"42" == "foo
Last updated