Это связано с тем, что когда любой операнд оператора эквивалентности является числом, почти во всех случаях другой операнд преобразуется в число, а затем сравнивается результат.Итак, вы заканчиваете сравнение 1
с 2
, а не true
с true
.Единственными исключениями из этого правила являются null
, undefined
и объекты, для которых значение по умолчанию (см. Не по теме ниже) составляет null
или undefined
;сравнение числа с этими возвращаемыми значениями false
(даже если Number(null)
равно 0
; не спрашивать).
Подробности в в спецификации , раздел 11.9.3: «Алгоритм сравнения абстрактного равенства» ( HTML версия ):
Сравнение x == y ,где x и y являются значениями, выдает true или false .Такое сравнение выполняется следующим образом:
Если тип ( x ) совпадает с типом ( y ), то
Если тип ( x ) не определен, вернуть true .
Если тип ()x ) - Null, возвращаемое true .
Если тип ( x ) равен Number, то
Если x равно NaN , вернуть false .
Если y is NaN , return false .
Если x такое же числовое значение, как y, вернуть true .
Если x равно + 0 и y равно −0 , возвращаемое true .
Если x равно −0 и y is + 0 , return true .
Return false .
If Type (x ) - String, затем возвращается true , если x и y - это абсолютно одинаковая последовательность символов (одинаковая длина и одинаковые символы в соответствующих позициях),В противном случае верните false .
Если тип ( x ) является логическим, верните true , если x и y оба true или оба false .В противном случае, верните false .
Return true , если x и y обратитесь ктот же объект.В противном случае верните false .
Если x равно null и y is undefined , return true .
Если x равно undefined и y равно пусто , возвращено верно .
Если тип ( x ) равен числуи тип ( y ) равен String,
возвращает результат сравнения x == ToNumber ( y ).
Если Type ( x ) равен String, а Type ( y ) равен Number,
возвращает результат сравнения ToNumber ( x )) == y .
Если тип ( x ) является логическим, вернуть результат сравнения ToNumber ( x *)1240 *) == y .
Если тип ( y ) - логическое значение, вернуть результат сравнения x == ToNumber ( y ).
Если тип ( x ) равен либо String, либоЧисло и тип ( y ) - это объект,
возвращает результат сравнения x == ToPrimitive ( y ).
Если тип ( x ) равен объекту, а тип ( y ) равен либо строке, либо числу,
возвращает результат сравнения ToPrimitive ()x ) == y .
Возврат false .
Если вы хотите проверить, что они оба правдивы или оба ложны, вы можете использовать идиому взрыва (!
) или двойного взрыва (!!
), чтобы привести их обоих к логическим значениям:
var a = true,
b = 2;
alert(a == b); // "false", 1 !== 2
alert(!!a == !!b); // "true", true === true
alert(!a == !b); // "true", false === false
a = false;
b = 0;
alert(a == b); // "true", 0 === 0
alert(!!a == !!b); // "true", false === false
alert(!a == !b); // "true", true === true
... но обычно использование ==
или !=
с логическими значениями не идеально. Но это подходит.
Я склонен использовать двойной удар, но в JavaScript нет причин для этого. (Существует аргумент для двойного по сравнению с единственным в некоторых других языках, хотя это слабый аргумент, связанный с согласованностью с if (!!x)
. В JavaScript вам никогда не нужен двойной удар в случае if (x)
, поэтому ...)
(Не по теме: значением по умолчанию для большинства объектов JavaScript является строка, хотя часто она похожа на «[объектный объект]», который в конечном итоге становится NaN
, если вы преобразуете его в число; но функции конструктора могут переопределить это поведение через valueOf
и toString
. Значением по умолчанию для хост-объектов является среда хоста.)