【问题标题】:JavaScript seems to evaluate an invalid result when comparing two values比较两个值时,JavaScript 似乎评估无效结果
【发布时间】:2015-12-20 14:24:49
【问题描述】:

如果我写如下代码:

" \t\r\n" == 0

JavaScript 将返回 true。但是,如果我手动将这两个值都转换为布尔值,那么:

!!" \t\r\n" // returns true
!!0 // returns false

这意味着 JavaScript 在第一个表达式中表示 true == false,但如果我比较转换为布尔值的值,则相反,这对我没有任何意义。

请注意,我写的不是!!"0",而是!!0——差别很大。

【问题讨论】:

标签: javascript


【解决方案1】:

对比

" \t\r\n" == 0

是真的,因为语言规范说它应该是真的。

让我们从Abstract Equality Comparison (x == y) 的算法开始

如果 Type(x) 是 String 并且 Type(y) 是 Number,则返回 比较ToNumber(x) == y.

看看那里说什么,如果第一个是字符串,它是,第二个是数字,它是,将第一个转换为基于ToNumber()操作的数字。

那么ToNumber() 操作是什么,here it is in the spec

应用于字符串的 ToNumber 将以下语法应用于输入 字符串。
如果语法不能将 String 解释为 StringNumericLiteral,则 ToNumber 的结果为 NaN。

关于如何使用ToNumber 转换不同字符串的整章非常复杂,但在规范中进一步说明

StringNumericLiteral ::: [empty]MV0
StringNumericLiteral ::: StrWhiteSpaceMV0

(MV = 数学值)

因此,任何为空或仅包含空格的字符串都将转换为0

让我们自己尝试强制字符串

console.log( +" \t\r\n" ); // gives the number 0

因此,包含空格、制表符和换行符的字符串被转换为0

因此,将字符串" \t\r\n" 转换为内部ToNumber() 操作会得到浏览器0,所以0 == 0 自然是true,这就是答案。

【讨论】:

    【解决方案2】:

    首先,您使用相等而不是严格相等来比较两个值。

    当使用==(相等)值时将被强制。使用===(严格相等)时不会发生这种情况。

    " \t\r\n" == 0 // returns true, these values are 'falsy', which are coerced to false 
    
    " \t\r\n" === 0 // returns false
    

    参考this question

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多