Basics

Истина и ложь

Особый список "ложных" значений в JavaScript таков:

  • ""(пустая строка)

  • 0,-0,NaN(некорректноечисло)

  • null,undefined

  • false

Любое значение, не входящее в этот "ложный" список — "истинно." Вот несколько примеров:

  • "hello"

  • 42

  • true

  • [ ],[ 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