Почему? 1 == "1" равно true и!! 2 == "2" равно false?

Как говорится в заголовке, почему:

> !!1=="1"

равно

True

и

> !!2=="2"

равны:

False

Аналогично, почему > "1"==true равно true и > "2"==true равно false

Я озадачен. Это просто ошибки в JS или что здесь происходит?

Ответ 1

В соответствии с правилами приоритета оператора логический ! имеет более высокий приоритет над ==. Итак, в обоих случаях сначала оценивается !!.

Примечание: Правка различных объектов объясняется в этом ответе.

Первый случай

!!1 == "1"

!1 будет оцениваться до false, так как 1 считается Truthy. Отрицая снова, получим true. Таким образом, выражение становится

true == "1"

Теперь применяются правила принуждения, так как вы использовали оператор ==, который оценивается как Алгоритм сравнения абстрактного равенства в спецификации ECMAScript 5.1,

6. Если Type(x) - Boolean, верните результат сравнения ToNumber(x) == y.

Итак, true будет преобразован в число, равное 1 согласно ToNumber алгоритм для логических значений. Теперь выражение становится

1 == "1"

Теперь

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

Итак, "1" будет преобразован в число, и это даст 1, согласно алгоритму ToNumber. Вот почему он показывает true в первом случае.

Второй случай

Здесь применяются те же правила.

!!2 == "2"

становится

true == "2"

затем

1 == "2"

который становится

1 == 2

который не является true, поэтому второй случай печатает false.

Ответ 2

TL;DR; это связано с [ToNumber] конверсиями в алгоритме оператора ==.

Первый шаг - упростить выражение. Поскольку !!x=="x" анализируется как (!!x)=="x" и !!a_truthy_expression -> true, фактическое релевантное выражение для равенства равно

!!1=="2" -> true=="1" -> Boolean==String
!!2=="2" -> true=="2" -> Boolean==String

Итак, посмотрим на правила для 11.9.3 Алгоритм сравнения абстрактного равенства и далее вместе с приложением дает

Правило 6 - Если тип (x) булев, верните результат сравнения ToNumber (x) == y.

что приводит к Number==String или 1 == "1" и 1 == "2", соответственно 1. Тогда правило

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

что приводит к Number==Number или 1 == 1 и 1 == 2, соответственно 1; последнее явно ложно.

Правило 1. Если тип (x) совпадает с типом (y), то [по c.iii.] Если x - это то же числовое значение, что и y, верните true [else return false].

(Тот же алгоритм объясняет случай String==Boolean, когда применяются дополнительные правила.)


1 Чтобы увидеть правило [ToNumber], используйте:

+false -> 0
+true  -> 1
+"1"   -> 1
+"2"   -> 2

Ответ 3

Его проблема с приоритетом оператора.

Оператор ! является унарным оператором. Это означает, что левая сторона должна быть выражением или логическим анализируемым разделом. См. Javascript MDN.

!!1==1 is not necessary !!(1==1)
!!2==2 is not necessary !!(2==2)

Я думаю, что эти выражения должны быть последовательными, если равный оператор имеет больше приоритетов, чем! оператор. Но если мы рассмотрим обратное, оценивая первые отрицания, имеем:

!!1 == 1
!1 -> false
!!1 -> true
!!1 == 1 

И с двумя

!!2==2
!2 -> false
!!2 -> true
(!!2) == 2 -> false

Это потому, что! оператор имеет приоритет над == operator

См. Предпочтения оператора Mozilla

Ответ 4

!!1 равно true, а "1" равно true ( "0" - false, так же как и любая другая строка). Итак, !!1 == "1" оценивается как true == true, который, конечно, возвращает true.

!!2 также равно true. Как я упоминал ранее, "2" не "1", поэтому он неверен. Поэтому мы имеем true == false, который, конечно, возвращает false.

Если вы хотите увидеть, является ли 2 (число) равным "2" (строковое представление числа), тогда все, что вам нужно сделать, это 2 == "2", который оценивается как 2 == 2, что верно, Разница в том, что мы не сравниваем логическое значение с логическим. Мы сравниваем число против числа.

В принципе, размещение !! перед числом преобразуется в логическое, что заставляет JavaScript отличать вашу строку от булева, а не от числа.

Ответ 5

Потому что "1" можно считать "истинным", когда вы выполняете проверку равенства, а не идентификатор, но "2" - не можете.