Is whitespace equals to integer 0 in Javascript?

2019-05-22 18:38发布

My app behaves abnormally and figured the code below is going to else statement unexpectedly.

code

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

Firebug output

bar

I thought whitespace is a String and comparison against integer zero should return false like the case above but I don't know why it is going to else statement.

Could anyone explain why?

5条回答
仙女界的扛把子
2楼-- · 2019-05-22 18:55

The other answers have told you how to solve the issue. My answer will attempt to actually explain why you have the issue in the first place (since that was your actual question!)

The behaviour of the == operator is defined in the spec as the "abstract equality algorithm". It states (among other things) the following:

If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.

One of the rules of the ToNumber operation on a string is as follows:

The MV of StringNumericLiteral ::: StrWhiteSpace is 0...

Once the exact MV for a String numeric literal has been determined, it is then rounded to a value of the Number type. If the MV is 0, then the rounded value is +0 unless the first non white space character in the String numeric literal is ‘-’, in which case the rounded value is −0.

So we are left with +0 == 0 which fits another rule of the abstract equality algorithm:

If x is the same Number value as y, return true.

This is the case because 0 is the same as +0. Even if one of the numbers was -0 it would return true:

If x is +0 and y is −0, return true.

If x is −0 and y is +0, return true.

查看更多
Ridiculous、
3楼-- · 2019-05-22 19:03

because a string with whitespaces is converted to 0. So To compare:


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

查看更多
干净又极端
4楼-- · 2019-05-22 19:04

When you use != rather than !==, JavaScript tries to coerce the values on either side to the same type. In this case, I think it converts both to numbers.

" " happens to be 0 as a number. (Try " " * 1. It evaluates to 0.)

This also works with other operators like > or *. So " " > -1 is true and " " * 100 is 0. This also means you can do neat stuff like "6" * "7" and get 42. Unfortunately, this breaks down with + since it is inexplicably overloaded to do both math and string concatenation.

I personally like all of this behavior except for +. Others' opinions vary.

查看更多
Evening l夕情丶
5楼-- · 2019-05-22 19:06

In JS, " " == 0 equals true with loose/lenient comparison, you should use strict equality operator ===/!== instead:

" " !== 0

To get to first condition.


Tests:

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

Loose Comparison Chart:

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

Strict Comparison Chart:

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

(Examples by Douglas Crockford)


Good Practice:

Whenever possible, use strict equality operator because with loose equality operator, JS does type coercion which is a performance hit and doesn't always yield expected results as shown in above comparison charts.

查看更多
我想做一个坏孩纸
6楼-- · 2019-05-22 19:09

to compare with the number 0, you must use the strict comparison ===

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

a "truth table" found here: Which equals operator (== vs ===) should be used in JavaScript comparisons?

查看更多
登录 后发表回答