В Javascript <int-value> == "<int-value>" оценивается как true. Почему это так? - PullRequest
10 голосов
/ 20 марта 2009

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

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

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

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

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

оповещение не происходит.

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

Ответы [ 8 ]

32 голосов
/ 20 марта 2009

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

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

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

  1. Если тип (x) отличается от типа (y), перейдите к шагу 14.
  2. Если тип (x) не определен, вернуть true.
  3. Если тип (x) равен нулю, вернуть true.
  4. Если тип (x) не является числом, перейдите к шагу 11.
  5. Если x равен NaN, вернуть false.
  6. Если y равен NaN, вернуть false.
  7. Если x совпадает с y, вернуть true.
  8. Если x равен +0, а y равен −0, вернуть true.
  9. Если x равен −0, а y равен +0, вернуть true.
  10. Вернуть false.
  11. Если Type (x) равен String, вернуть true, если x и y абсолютно совпадают последовательность символов (одинаковая длина и те же символы в соответствующих позиции). В противном случае верните false.
  12. Если Type (x) - логическое значение, вернуть true, если x и y оба - true или оба ложный. В противном случае верните false.
  13. Вернуть true, если x и y относятся к одному и тому же объекту или если они ссылаются на объекты соединены друг с другом (см. 13.1.2). В противном случае верните false.
  14. Если x равен нулю, а y не определен, вернуть true.
  15. Если x не определен, а y равен нулю, вернуть true.
  16. Если Type (x) равен Number, а Type (y) равен String, вернуть результат сравнение x == ToNumber (y).
  17. Если Type (x) равен String, а Type (y) равен Number, вернуть результат сравнение ToNumber (x) == y.
  18. Если тип (x) - логическое значение, вернуть результат сравнения ToNumber (x) == y.
  19. Если тип (y) является логическим, вернуть результат сравнения x == ToNumber (у).
  20. Если для Type (x) задано либо String, либо Number, а для Type (y) - Object, вернуть результат сравнения х == ToPrimitive (у).
  21. Если тип (x) равен объекту, а тип (y) равен либо строковому, либо числовому, возвращает результат сравнения ToPrimitive (x) == y.
  22. Вернуть 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
12 голосов
/ 20 марта 2009

Делаем это:

if(5 == "5")

Заставляет javascript конвертировать первые 5 в строку. Попробуйте это:

if(5 === "5")

=== также позволяет Javascript оценивать тип.

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

7 голосов
/ 20 марта 2009

Поскольку 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 голосов
/ 20 марта 2009

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

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

1 голос
/ 20 марта 2009

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

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

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

1 голос
/ 20 марта 2009

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

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

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

5 === "5" ложь "string" === "string" true

1 голос
/ 20 марта 2009

Javascript не приводит «false» к логическому false, только к строке «false».

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

0 голосов
/ 02 января 2011

JavaScript определяет значения Falsey равными 0, логические значения false и undefined. Любая строка за пределами «0» будет истинной, даже если эта строка «ложная».

Немного раздражает, правда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...