36

今天我在做一些实验的时候==,我无意中发现了这一点"\n\t\r" == 0。到底如何"\n\t\r"等于0,或false

我所做的是:

var txt = "\n";  //new line
txt == 0;        //it gives me true

这真的让我很恼火。所以我做了更多:

var txt = "\r";  //"return"
txt == 0;        //true

var txt = "\t";  //"tab"
txt == 0;        //true

这根本没有意义。这是怎么回事?更疯狂的是:

//Checking for variable declared or not

var txt ="\n\t\r";
if(txt!=false){
    console.log("Variable is declared.");
}else{
    console.log("Variable is not declared.");
}

它给我的是Variable is not declared.

它如何等于0, 或false???

4

5 回答 5

41

这种行为可能令人惊讶,但可以通过查看规范来解释。

我们必须看看在执行与等号运算符的比较时会发生什么。确切的算法在第 11.9.3 节中定义。

我构建了一个简单的工具来演示执行了哪些算法步骤:https ://felix-kling.de/js-loose-comparison/


string == integer

我们必须查看的步骤是#5:

5.如果Type(x)是String,Type(y)是Number,
返回比较的结果ToNumber(x) == y

这意味着字符串"\n"( "\r", "\t") 首先转换为数字,然后与0.

字符串如何转换为数字?这在第 9.3.1 节中进行了解释。简而言之,我们有:

的 MV(数学值)StringNumericLiteral ::: StrWhiteSpace0

其中StrWhiteSpace定义为

StrWhiteSpace :::
    StrWhiteSpaceChar StrWhiteSpace_opt

StrWhiteSpaceChar :::
    WhiteSpace
    LineTerminator

这只是意味着包含空格字符和/或行终止符的字符串的数值是0.
哪些字符被视为空白字符在第 7.3 节中定义。


string == boolean

我们必须查看的步骤是#7:

7. 如果 Type(y) 为 Boolean,则返回比较结果x == ToNumber(y)

布尔值如何转换为数字非常简单:truebecome1falsebecome 0

之后我们将一个字符串与一个数字进行比较,这在上面已经解释过了。


===正如其他人所提到的,可以使用严格比较 ( ) 来避免这个“问题”。实际上,如果您知道自己在做什么并且想要这种行为,那么您应该只使用正常比较。

于 2012-04-29T23:50:46.997 回答
12

因为 JavaScript 是一种松散类型的语言,它会尝试将比较的第一方类型转换为另一方,以便它们相互匹配。

任何不包含数字的字符串在与整数比较时变为 0,在与布尔值比较时变为真(在某些情况下除外)。

轻阅读材料。

于 2012-04-29T21:38:29.177 回答
4

txt不是Boolean,所以永远不会false。不过也可以undefined

var txt ="\n\t\r";
if(txt !== undefined) { //or just: if (txt)
    console.log("Variable is declared.");
} else {
    console.log("Variable is not declared.");
}
//=> will log: 'Variable is declared.'

顺便说一句,声明的变量可能是undefined(例如var txt;)。

如果您进行更严格的比较(没有类型强制,使用===),您会看到

var txt = '\n'; txt === 0; //=> false
var txt = '\r'; txt === 0; //=> false
var txt = '\t'; txt === 0; //=> false

也可以看看

于 2012-04-29T21:40:15.220 回答
1

原因是"\n\t\r"as" "被视为空字符串。如果您使用==它将返回true,但如果您使用===它将返回false

如果你想测试是否存在,你应该使用类似的东西

if(typeof strName !== 'undefined') {
    /*do something with strName*/
} else {
    /*do something without it*/
}
于 2012-04-29T21:41:52.823 回答
1

每当您使用== operatorand 尝试将字符串与数字进行比较时,字符串将首先转换为数字。因此:alert("\n\r"==0) becomes: alert(Number("\n\r")==0) 数字结构有点有趣。它将首先去除空格,然后确定数字是否不是数字。如果NaN,则结果为“ NaN”。如果字符串为空,则结果为 0。

alert(Number()) alerts 0
alert(Number("")) alerts 0
alert(Number(" \n \r \n \t")) alerts 0
alert(Number("blah")) alerts NaN
alert(Number("0xFF")) alerts 255
alert(Number("1E6")) alerts 1000000

要检查结果是否为 NaN,请使用 isNaN()

Thus: alert(isNaN("blah")) alerts true
Thus: alert(isNaN("")) alerts false
Thus: alert(isNaN("\n")) alerts false
Thus: alert(isNaN(" ")) alerts false

但是请注意,NaN 永远不会等于 NaN:

var nan=Number("geh");alert(nan==nan);  alerts false 

更新:

如果要检查双方是否为 NaN,则首先将两者都转换为布尔值,如下所示:

var nan=Number("geh");alert(!!nan==!!nan); alerts true

或者更好

var nan=Number("geh");
alert(isNaN(nan)&& isNaN(nan));
于 2012-04-30T00:51:36.587 回答