【问题标题】:'\n\t\r' == 0 is true?'\n\t\r' == 0 是真的吗?
【发布时间】:2012-04-29 21:34:22
【问题描述】:

今天在用==做实验的时候,无意中发现"\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.

怎么等于0,或者false???

【问题讨论】:

  • 我会说“因为字符串是空的”
  • @Mehrdad - 哈哈,它用 JavaScript 写着 0.1 + 0.2 --> 0.30000000...4 我不相信,我试过了,我得到了同样的结果。以前从未注意到它!
  • @Derek:这是您在使用 IEEE 浮点数的每种语言中都会看到的一些行为(几乎是所有语言)

标签: javascript


【解决方案1】:

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

我们必须看看与equals operator 进行比较时会发生什么。具体算法在section 11.9.3中定义。

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


string == integer

我们要看的步骤是#5:

5。如果Type(x) 是字符串,Type(y) 是数字,
返回比较结果ToNumber(x) == y

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

如何将字符串转换为数字?这在section 9.3.1 中有解释。简而言之,我们有:

StringNumericLiteral ::: StrWhiteSpace 的 MV(数学值)是0

StrWhiteSpace 定义为

StrWhiteSpace :::
    StrWhiteSpaceChar StrWhiteSpace_opt

StrWhiteSpaceChar :::
    WhiteSpace
    LineTerminator

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


string == boolean

我们要看的步骤是#7:

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

如何将布尔值转换为数字非常简单:true 变为 1false 变为 0

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


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

【讨论】:

    【解决方案2】:

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

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

    Light reading material.

    【讨论】:

    • 这不是错误,而是功能!
    • 你的答案有点混乱——如果一个字符串与一个字符串进行比较,它肯定仍然是一个字符串(也许你想在那里说“数字”?)。
    • 关于“任何不包含数字的字符串,与整数相比都为0”,那"abc" == 0 // false怎么解释?
    • 声明的第二部分也不正确:“当与布尔值比较时,它变为真(如果不是空字符串)”"0" == false 产生 true。根据您的解释,"0" 将转换为true,因此它应该产生false。实际上,两个操作数都先转换为数字,然后进行比较。请注意,比较一个字符串到一个布尔值和评估一个字符串as布尔值是有区别的。
    • 确实@FelixKling,应该提到"string"==0 基本上被解释为Number("string")==0。由于某种原因,空白字符串被强制转换为 0,而带有字符的字符串被强制转换为 NaN
    【解决方案3】:

    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
    

    See also

    【讨论】:

    • !== 禁用类型转换,所以即使txt !== false 也会给你true
    【解决方案4】:

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

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

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

    【讨论】:

    • 我认为 JavaScript 不能接受这些引号作为字符串分隔符。
    • 你错了——只有 "" 是一个空字符串," " 不是。试试if (" ") alert("hi"); 看看它的实际效果。
    • > " " == 0 使用 node.js 返回true
    • 没错,因为 " " 是一个字符串 - 如果你将它与一个数字(0 是什么)进行比较,它也会在比较值之前转换为一个数字 - 因此实际比较将是“0 === 0”,这是真的。
    • 这不是因为它是一个字符串,因为如果您测试"test" == 0,它将返回false。 " " 是一个空字符串,而 "test" 不是。
    【解决方案5】:

    每当您使用== operator 并尝试将字符串与数字进行比较时,字符串将首先转换为数字。因此:alert("\n\r"==0) becomes: alert(Number("\n\r")==0) Number 结构有点有趣。它将首先去除空格,然后确定数字是否不是数字。如果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));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-22
      • 1970-01-01
      • 2010-09-18
      相关资源
      最近更新 更多