В Javascript значение <int-value> == "<int-value>" соответствует true. Почему это так?

Если я делаю 0 == "0", он получает значение true. Попробуйте,

if( -777 == "-777" ) alert("same");

появляется предупреждение.

И также заметно, что true == "true" не оценивает true. Попробуйте,

if( false == "false" ) alert("same");

предупреждение не происходит.

Почему это так?

Ответы

Ответ 1

Поведение == немного длинное, но четко определенное в ecma-262 spec:

11.9.3 Алгоритм сравнения абстрактного равенства

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

  • Если тип (x) отличается от типа (y), перейдите к шагу 14.
  • Если тип (x) равен Undefined, верните true.
  • Если Type (x) - Null, верните true.
  • Если Type (x) не является числом, перейдите к шагу 11.
  • Если x является NaN, верните false.
  • Если y является NaN, верните false.
  • Если x - это то же числовое значение, что и y, верните true.
  • Если x равно +0 и y равно -0, верните true.
  • Если x равно -0 и y равно +0, верните true.
  • Возвращает false.
  • Если Type (x) - String, тогда верните true, если x и y точно совпадают последовательность символов (одинаковая длина и одинаковые символы в соответствующих позиции). В противном случае верните false.
  • Если тип (x) является логическим, верните true, если x и y оба true или оба ложный. В противном случае верните false.
  • Возвращает true, если x и y относятся к одному и тому же объекту или если они ссылаются на объекты, соединенные друг с другом (см. 13.1.2). В противном случае верните false.
  • Если x равно null, а y - Undefined, верните true.
  • Если x равно undefined, а y - null, верните true.
  • Если Type (x) - Number и Type (y) - String, верните результат сравнение x == ToNumber (y).
  • Если Type (x) - String и Type (y) - Number, верните результат сравнение ToNumber (x) == y.
  • Если Type (x) является логическим, верните результат сравнения ToNumber (x) == y.
  • Если тип (y) булев, верните результат сравнения x == ToNumber (у).
  • Если Type (x) является либо String, либо Number и Type (y) - Object, return результат сравнения x == ToPrimitive (у).
  • Если Type (x) является Object и Type (y) является либо строкой, либо номером, верните результат сравнения ToPrimitive (x) == y.
  • Возвращает false.

Шаг 16 применяется к вашему предыдущему примеру:

   0 == "0"            // apply 16
≡  0 == toNumber("0")
≡  0 == 0              // apply 7
≡  true

И шаг 18, ​​затем шаг 16, применим к последнему:

   true == "true"            // apply 18
≡  toNumber(true) == "true"
≡  1 == "true"               // apply 16
≡  1 == toNumber("true")
≡  1 == NaN                  // apply 6
≡  false

Ответ 2

Выполнение этого действия:

if(5 == "5")

Делает javascript преобразовывает первые 5 в строку. Попробуйте следующее:

if(5 === "5")

=== также делает Javascript для оценки типа.

Это на самом деле дубликат этого question, где это объясняется очень хорошо.

Ответ 3

Поскольку Javascript свободно набирается, он будет молча использовать ваши переменные в зависимости от операции и типа других переменных в операции.

alert ("5" - 1);  // 4  (int)
alert ("5" + 1);  // "51" (string) "+" is a string operator, too
alert ("5" == 5); // true

Что вы можете посмотреть, это проверка идентификации (===). Это гарантирует, что переменные одинаковы, а не просто равны.

alert("5" == 5);  // true, these are equal
alert("5" === 5); // false, these are not identical.

Также см. этот вопрос: Чем отличаются операторы сравнения равенства и идентичности? Реализация PHP очень похожа на javascript.

Ответ 4

В JavaScript есть два набора операторов равенства:

  • === and !== (строгие операторы равенства)
  • == and != (стандартные операторы равенства)

Стандартные операторы равенства будут делать правильное сравнение, если оба операнда одного типа, но вы можете получить неожиданные результаты, если они не являются одним и тем же типом, например:

'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true

Для этого я всегда рекомендую использовать строгие операторы равенства (===,! ==).

Ответ 5

Javascript не генерирует "false" для boolean false, только для строки "false".

Вы можете свободно вводить строковые значения в их целочисленный эквивалент, поэтому ваш первый пример работает.

Ответ 6

Javascript - это свободно типизированный язык, поэтому приведения типов выполняется во время выполнения, когда интерпретатор считает, что это необходимо. Если вы сравниваете целое число со строкой, это означает, что они должны быть одного и того же типа, поэтому, например, "34" == 34 истинно, поскольку целое число, вероятно, было бы приложено к строке перед сравнением.

Строка "false" не указана в bool, вместо этого bool false присваивается строкой, которая имеет значение "0", то есть строку, содержащую число 0, дающую "0", == "false", что, очевидно, неверно.

Если вы хотите сравнить значение без автоматического typecasting, эффективно сравнивая типы, а также значения, используйте тройной равный:

5 === "5" false "string" === "string" true

Ответ 7

Почему это так?

Потому что JavaScript и несимметричный, и дико непоследовательный. Не все его конструктивные особенности хорошо продуманны; он был создан, реализован и развернут невероятно быстро по сравнению с любым другим языком программирования, в спешке, чтобы получить Netscape 2.0. Только после этого он улегся, потерял некоторые из более вопиющих ошибок и стал полустандартизированным.

Ищете какое-то философское обоснование для таких вещей, как неявные правила литья, скорее всего, будут бесплодным упражнением. Единственный, действительно последовательный принцип JavaScript придерживается DWIM, очень в отрицательном смысле.

Ответ 8

JavaScript определяет значения falsey равными 0, boolean false и undefined. Любая строка за пределами "0" будет истинна, даже если эта строка "false".

На самом деле это раздражает.