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