JavaScript правда в булевом сравнении чисел - PullRequest
5 голосов
/ 10 июля 2011

Я новичок в JavaScript и пытаюсь научиться этому на интернет-ресурсах. В то время как я знаю, что будет много материала, но большинство людей, похоже, согласились с этим - правдивость вещей в JS (просто для примера: здесь )

Теперь я обнаружил эту странную вещь в своих экспериментах:

(true == 2) - это false. почему?

Насколько я знаю, 2 - это ненулевое число , поэтому его следует оценивать как true.

Ответы [ 3 ]

9 голосов
/ 10 июля 2011

Это связано с тем, что когда любой операнд оператора эквивалентности является числом, почти во всех случаях другой операнд преобразуется в число, а затем сравнивается результат.Итак, вы заканчиваете сравнение 1 с 2, а не true с true.Единственными исключениями из этого правила являются null, undefined и объекты, для которых значение по умолчанию (см. Не по теме ниже) составляет null или undefined;сравнение числа с этими возвращаемыми значениями false (даже если Number(null) равно 0; не спрашивать).

Подробности в в спецификации , раздел 11.9.3: «Алгоритм сравнения абстрактного равенства» ( HTML версия ):

Сравнение x == y ,где x и y являются значениями, выдает true или false .Такое сравнение выполняется следующим образом:

  1. Если тип ( x ) совпадает с типом ( y ), то

    1. Если тип ( x ) не определен, вернуть true .

    2. Если тип ()x ) - Null, возвращаемое true .

    3. Если тип ( x ) равен Number, то

      1. Если x равно NaN , вернуть false .

      2. Если y is NaN , return false .

      3. Если x такое же числовое значение, как y, вернуть true .

      4. Если x равно + 0 и y равно −0 , возвращаемое true .

      5. Если x равно −0 и y is + 0 , return true .

      6. Return false .

    4. If Type (x ) - String, затем возвращается true , если x и y - это абсолютно одинаковая последовательность символов (одинаковая длина и одинаковые символы в соответствующих позициях),В противном случае верните false .

    5. Если тип ( x ) является логическим, верните true , если x и y оба true или оба false .В противном случае, верните false .

    6. Return true , если x и y обратитесь ктот же объект.В противном случае верните false .

  2. Если x равно null и y is undefined , return true .

  3. Если x равно undefined и y равно пусто , возвращено верно .

  4. Если тип ( x ) равен числуи тип ( y ) равен String,
    возвращает результат сравнения x == ToNumber ( y ).

  5. Если Type ( x ) равен String, а Type ( y ) равен Number,
    возвращает результат сравнения ToNumber ( x )) == y .

  6. Если тип ( x ) является логическим, вернуть результат сравнения ToNumber ( x *)1240 *) == y .

  7. Если тип ( y ) - логическое значение, вернуть результат сравнения x == ToNumber ( y ).

  8. Если тип ( x ) равен либо String, либоЧисло и тип ( y ) - это объект,
    возвращает результат сравнения x == ToPrimitive ( y ).

  9. Если тип ( x ) равен объекту, а тип ( y ) равен либо строке, либо числу,
    возвращает результат сравнения ToPrimitive ()x ) == y .

  10. Возврат 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. Значением по умолчанию для хост-объектов является среда хоста.)

2 голосов
/ 10 июля 2011

Логическая константа true переводится в число, равное 1.

1 голос
/ 10 июля 2011

При нестрогом сравнении (==), если операнды не относятся к одному и тому же типу, они будут приводиться / приводиться и строго сравниваться, причем первое предпочтение будет отдано числам, если операндом является число или логическое значение ( MDN ).

Таким образом, true == 2 оценивается как Number(true) === 2, что равно 1 === 2, что ложно.

Конечно, вы всегда можете заставить вещи сравнивать, как хотитек ним, что является явным и может решить труднодоступные проблемы позже:

true === Boolean(2) верно.

...