【问题标题】:Why does !!1=="1" equal true and !!2=="2" equal false?为什么 !!1=="1" 等于 true 而 !!2=="2" 等于 false?
【发布时间】:2014-07-04 18:39:22
【问题描述】:

如标题所述,为什么会这样:

> !!1=="1"

等于

True

> !!2=="2"

等于:

False

同样,为什么> "1"==true等于true> "2"==true等于false

我很困惑。这些只是 JS 中的错误还是这里发生了什么?

【问题讨论】:

  • @Michael: 2==“2” 对你来说等于假吗?对我来说它工作正常jsfiddle.net/HGEcs
  • 这就是为什么你应该始终使用=== 在 JavaScript 中进行比较。
  • 不,这不是错误。如果您不知道布尔值的含义,则根本不应该将布尔值与字符串进行比较。
  • 取决于您所说的“错误”。在通常意义上,不,这不是错误 - 但它设计缺陷。
  • 请注意这些不是重复的。我们这里考虑的是比较布尔值到数字字符串的情况,而不是类似的情况。

标签: javascript


【解决方案1】:

因为当您进行相等性检查时,“1”可能被认为是“真”,而不是身份,但“2” - 不能。

【讨论】:

  • 考虑 !!2!!1 - 两者都评估为 true(因此,1 和 2 都是真值)
【解决方案2】:

tldr;这是由于== 运算符算法中的[ToNumber] 转换。

第一步是简化表达式。由于!!x=="x" 被解析为(!!x)=="x"!!a_truthy_expression -> true,因此等式的实际相关表达式为

!!1=="2" -> true=="1" -> Boolean==String
!!2=="2" -> true=="2" -> Boolean==String

然后查看11.9.3 The Abstract Equality Comparison Algorithm 的规则并跟随应用程序产生

规则 6 - 如果 Type(x) 是 Boolean,则返回比较结果 ToNumber(x) == y。

分别导致Number==String 或 1=="1" 和 1=="2"1。然后是规则

规则 7 - 如果 Type(x) 是 Number 并且 Type(y) 是 String, 返回比较结果 x == ToNumber(y)。

被应用,结果分别为Number==Number 或 1==1 和 1==21;后者显然是错误的。

规则 1 - 如果 Type(x) 与 Type(y) 相同,则 [by c.iii.] 如果 x 与 y 的数值相同,则返回 true [否则返回 false]。

(当应用补充规则时,相同的算法解释了String==Boolean 的情况。)


1要查看应用的 [ToNumber] 规则,请考虑:

+false -> 0
+true  -> 1
+"1"   -> 1
+"2"   -> 2

【讨论】:

    【解决方案3】:

    这是一个优先运算符问题。

    ! 运算符是一元运算符。这意味着左侧必须是表达式或布尔可评估部分。见Javascript MDN

    !!1==1 is not necessary !!(1==1)
    !!2==2 is not necessary !!(2==2)
    

    我认为如果等号运算符的优先级高于!操作员。但如果我们考虑相反的情况,评估我们的第一个否定:

    !!1 == 1
    !1 -> false
    !!1 -> true
    !!1 == 1 
    

    还有两个

    !!2==2
    !2 -> false
    !!2 -> true
    (!!2) == 2 -> false
    

    那是因为 !运算符优先于 == 运算符

    Mozilla Operator Preference

    【讨论】:

      【解决方案4】:

      !!1 等于真,“1”等于真(“0”为假,其他字符串也是如此)。所以!!1 == "1" 的计算结果为true == true,当然返回true。

      !!2 也等于 true。正如我之前提到的,“2”不是“1”,所以它是错误的。因此,我们有true == false,当然返回false。

      如果您想查看 2(一个数字)是否等于“2”(一个数字的字符串表示形式),那么您所要做的就是 2 == "2",其计算结果为 2 == 2,这是真的.不同之处在于我们没有将布尔值与布尔值进行比较。我们正在将一个数字与一个数字进行比较。

      基本上,将!! 放在数字前面会转换为布尔值,这会强制 JavaScript 将字符串转换为布尔值而不是数字。

      【讨论】:

      • 这正是我所说的。
      • 你说:正如我之前提到的,“2”不是“1”。他说2 == 1 ??...试着解释一下这一点跨度>
      • 我说过“1”是唯一等于true的字符串。因此,“2”等于假,这给出了表达式true == false,因此!!2 == "2" 是假的。
      • -1。字符串没有被转换为布尔值。布尔值被转换为数字。此外,""0" is false" 令人困惑(如果没有错的话),因为 "0" 是真实的:!!"0" === true"0" == false
      • -1。 !!"" === false!!anyOtherString === true。换句话说,空字符串是假的,所有其他字符串都是真的。您的第一句话与此直接矛盾
      【解决方案5】:

      根据Operator precedence 规则,逻辑! 的优先级高于==。因此,在这两种情况下,首先评估 !!

      注意:我的this answer已经解释了各种对象的真实性。

      第一种情况

      !!1 == "1"
      

      !1 将被评估为false,因为1 被认为是真实的。再次否定我们得到true。所以表达式变成了

      true == "1"
      

      现在,当您使用 == 运算符时,强制规则开始生效,该运算符根据 ECMAScript 5.1 规范中定义的 The Abstract Equality Comparison Algorithm 进行评估,

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

      因此,true 将被转换为一个数字,根据 ToNumber algorithm for Boolean values,它是 1。现在表达式变成了

      1 == "1"
      

      现在,

      4。如果Type(x)Number 并且Type(y)String, 返回比较结果x == ToNumber(y)

      因此,"1" 将被转换为一个数字并给出 1,就像 ToNumber algorithm 一样。这就是为什么它在第一种情况下显示true

      第二种情况

      此处应用相同的规则。

      !!2 == "2"
      

      变成

      true == "2"
      

      然后

      1 == "2"
      

      变成了

      1 == 2
      

      这不是true,这就是为什么第二种情况打印false

      【讨论】:

      • +1 难怪:100==true 总是假的。这让一些困惑如在; Negative NumbersPositive Number == true 除了 1 是一个正数之外,如何才能成为 false?...您的解释确实在这个问题上掩盖了一些 GreatLight。主要是点4.
      • @MichaelRader 如果您想比较这些值,那么您可能需要使用=== 运算符,它使用Strict Equality Algorithm
      • @MichaelRader 当然可以,但在深入了解=== 的限制之前,请先阅读文档;-)
      • 我喜欢人们逐步分解代码,因为并非所有人都知道后台发生了什么。谢谢!
      • 如果你想用这个创建一个语句,你可能会选择一个小布尔代数,所以如果你有var1 = 2var2 = 2,那么你可以使用if !!var1 and var2,因为您不是在检查这些数字的整数值,而是想要它们的布尔值。
      猜你喜欢
      • 2013-08-17
      • 2022-04-12
      • 1970-01-01
      • 2021-10-08
      • 2013-01-05
      • 1970-01-01
      • 1970-01-01
      • 2014-02-16
      • 2016-05-14
      相关资源
      最近更新 更多