Является ли пробел равным целому 0 в Javascript? - PullRequest
2 голосов
/ 16 февраля 2012

Мое приложение работает ненормально и полагает, что приведенный ниже код неожиданно преобразуется в оператор else.

код

if(" " != 0) {
    console.log("whitespace is not zero");
}
else {
    console.log("bar");
}

Вывод Firebug

bar

Я думал, что пробел - это строка, и сравнение с целым нулем должно возвращать ложь, как в случае, приведенном выше, но я не знаю, зачем это утверждение else.

Может кто-нибудь объяснить, почему

Ответы [ 5 ]

7 голосов
/ 16 февраля 2012

В JS " " == 0 равняется true при свободном / мягком сравнении, вы должны использовать оператор строгого равенства === / !== вместо:

" " !== 0

Чтобы добраться до первого состояния.


Тесты:

console.log(" " == 0); // true
console.log(" " === 0); // false

Свободная сравнительная таблица:

""           ==   "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

Строгая сравнительная таблица:

""           ===   "0"           // false
0            ===   ""            // false
0            ===   "0"           // false
false        ===   "false"       // false
false        ===   "0"           // false
false        ===   undefined     // false
false        ===   null          // false
null         ===   undefined     // false
" \t\r\n"    ===   0             // false

(Примеры Дугласа Крокфорда)


Хорошая практика:

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

2 голосов
/ 16 февраля 2012

В других ответах рассказывалось, как решить проблему.В моем ответе я попытаюсь объяснить , почему у вас проблема во-первых (поскольку это был ваш фактический вопрос!)

Поведение оператора == определено в спецификации.как « алгоритм абстрактного равенства ».В нем говорится (среди прочего) следующее:

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

Одно из правил операции ToNumber для строки выглядит следующим образом:

МЗ StringNumericLiteral ::: StrWhiteSpace равно 0...

После определения точного MV для числового литерала String он округляется до значения типа Number.Если MV равно 0, то округленное значение равно +0, если только первый непробельный символ в строковом числовом литерале не равен '-', в этом случае округленное значение равно -0.

Таку нас осталось +0 == 0, что соответствует другому правилу алгоритма абстрактного равенства:

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

Этослучай, потому что 0 совпадает с +0.Даже если бы одно из чисел было -0, оно вернуло бы true:

Если x равно +0 и y равно −0, верните true.

Если x равен −0, а y равен +0, вернуть true.

2 голосов
/ 16 февраля 2012

Когда вы используете != вместо !==, JavaScript пытается привести значения с обеих сторон к одному и тому же типу. В этом случае, я думаю, он конвертирует оба числа.

" " бывает 0 как число. (Попробуйте " " * 1. Оценивается 0.)

Это также работает с другими операторами, такими как > или *. Таким образом, " " > -1 - это истина, а " " * 100 - это 0. Это также означает, что вы можете делать аккуратные вещи, такие как "6" * "7" и получать 42. К сожалению, это ломается с +, так как он необъяснимо перегружен для выполнения математических и строковых конкатенаций.

Лично мне нравится все это поведение, кроме +. Мнения других людей различны.

1 голос
/ 16 февраля 2012

, поскольку строка с пробелами преобразуется в 0 . Так Для сравнения:


if(" " !== 0) {
....

1 голос
/ 16 февраля 2012

для сравнения с числом 0 вы должны использовать строгое сравнение ===

if(" " !== 0) {
    console.log("whitespace is not zero");
}
else {
    console.log("bar");
}

найденную здесь "таблицу истинности": Какой оператор равен (== vs ===)следует использовать в сравнениях JavaScript?

...