'\n\t\r' == 0 是真的吗?

'\n\t\r' == 0 is true?

提问人:Derek 朕會功夫 提问时间:4/30/2012 更新时间:12/29/2020 访问量:4600

问:

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

我所做的是:

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.

它如何等于 或 ???0false

JavaScript的

评论

33赞 user541686 4/30/2012
欢迎使用 Javascript
2赞 JustSid 4/30/2012
我会说“因为字符串是空的”
1赞 Derek 朕會功夫 4/30/2012
@Mehrdad - 哈哈,它在 JavaScript 中说,我不相信它,我尝试了,我得到了同样的东西。以前从未注意到它!0.1 + 0.2 --> 0.30000000...4
8赞 Holger Just 4/30/2012
@Derek:这是您在使用IEEE浮点数的每种语言中都会看到的一些行为(这与每种语言有关)
4赞 Holger Just 4/30/2012
还有这个:destroyallsoftware.com/talks/wat

答:

12赞 Madara's Ghost 4/30/2012 #1

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

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

轻便的阅读材料。

评论

11赞 user541686 4/30/2012
这不是一个错误,而是一个功能!
2赞 Niko 4/30/2012
你的答案有点令人困惑 - 如果将字符串与字符串进行比较,它肯定仍然是字符串(也许你想在那里说“数字”?
2赞 Felix Kling 4/30/2012
关于“任何不包含数字的字符串,与整数相比变为 0”,您如何解释?"abc" == 0 // false
2赞 Felix Kling 4/30/2012
此外,该语句的第二部分是不正确的:“与布尔值相比,并且变为真(如果不是空字符串)。 收益 率。根据您的解释,将转换为 ,因此它应该产生 。事实上,这两个操作数首先被转换为数字,然后进行比较。请注意,将字符串与布尔值进行比较将字符串评估布尔值是有区别的。"0" == falsetrue"0"truefalse
0赞 TarVK 12/29/2020
事实上@FelixKling,应该提到基本上被解释为 .由于某种原因,空格字符串被强制转换为 0,带有字符的字符串被强制转换为 ."string"==0Number("string")==0NaN
4赞 KooiInc 4/30/2012 #2

txt不是一个,所以它永远不会是。不过可以。Booleanfalseundefined

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.'

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

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

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

另请参阅

评论

3赞 Madara's Ghost 4/30/2012
!==禁用类型转换,因此甚至会给您。txt !== falsetrue
1赞 Jérémie Parker 4/30/2012 #3

原因是,就像被视为空字符串一样。 如果你使用它,它将返回,但如果你使用它,它将返回."\n\t\r"" "==true===false

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

if(typeof strName !== 'undefined') {
    /*do something with strName*/
} else {
    /*do something without it*/
}

评论

1赞 Madara's Ghost 4/30/2012
我不认为这些引号被 JavaScript 作为字符串分隔符接受。
0赞 Niko 4/30/2012
你错了 - 只有 “” 是空字符串,“” 不是。试着看看它的实际效果。if (" ") alert("hi");
0赞 Jérémie Parker 4/30/2012
> " " == 0使用 node.js 返回true
0赞 Niko 4/30/2012
没错,因为 “ ” 是一个字符串 - 如果你把它与一个数字(0 是什么)进行比较,它也会在比较值之前转换为一个数字 - 因此实际的比较将是 “0 === 0”,这肯定是正确的。
0赞 Jérémie Parker 4/30/2012
这不是因为它是一个字符串,因为如果你测试它会返回.“ ” 是空字符串,而 “test” 不是。"test" == 0false
42赞 Felix Kling 4/30/2012 #4

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

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

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


string == integer

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

5. 如果 is String 且 is Number,
则返回比较结果。
Type(x)Type(y)ToNumber(x) == y

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

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

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

其中定义为StrWhiteSpace

StrWhiteSpace :::
    StrWhiteSpaceChar StrWhiteSpace_opt

StrWhiteSpaceChar :::
    WhiteSpace
    LineTerminator

这仅表示包含空格字符和/或行终止符的字符串的数值为 。
哪些字符被视为空格字符在第 7.3 节中定义。
0


string == boolean

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

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

如何将布尔值转换为数字非常简单:becomes 和 becomes .true1false0

之后,我们将字符串与数字进行比较,如上所述。


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

1赞 Thalaivar 4/30/2012 #5

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

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));