【问题标题】:Difference between equality checking inside 'if condition' vs 'console.log' [duplicate]“if condition”与“console.log”内的相等检查之间的区别[重复]
【发布时间】:2019-04-04 23:20:27
【问题描述】:

我正在尝试一个代码 sn-p,但在 console.log 语句和条件语句中的空数组检查结果是不同的。 帮助/思考为什么会有所不同? 提前致谢!

//Output: true
if([]) {
  console.log(true)
} else{
  console.log(false)
}

//Output: false
console.log([] == true)

【问题讨论】:

  • [] 等于一个不是假值的数组,如 undefined 或 null 等,这就是为什么它返回 true 尝试使用变量,你会看到,[] == true 这测试是否数组是否为空
  • Comparing 一个值 with 一个布尔值不同于 converting 一个值 to 一个布尔值。
  • [] 是一个真值,这意味着它在 if 的布尔上下文中被认为是真的。真实值是所有未指定为虚假的值(“”、0、NaN、未定义、null、false)。这就是为什么true 首先被打印出来的原因。比较时,Javascript 首先将任何非布尔类型转换为其字符串表示形式。如果对空数组调用 toString 方法,则会得到空字符串。所以console.log([] == true)本质上变成了console.log("" == true)ecma-international.org/ecma-262/9.0/index.html#sec-toprimitive
  • @manonthemat: “在比较时,Javascript 首先将任何非布尔类型转换为它的字符串表示形式。” 这是不正确的。例如。数字不会转换为字符串。正确的说法是:将原始值与对象进行比较时,将对象转换为原始值。将非布尔值与布尔值进行比较时,布尔值将转换为数字。

标签: javascript


【解决方案1】:

您似乎遇到了一个已知的 JavaScript 怪癖。

“[] 是真的,但不是真的”

问题不在于您在哪里进行评估,而在于看起来相同的两个评估实际上是不同的。

https://github.com/denysdovhan/wtfjs#-is-truthy-but-not-true

【讨论】:

    【解决方案2】:

    我的假设是 if/else 块,在其“真实”测试的一部分中是检查是否存在某些东西(不仅仅是它是否为真)——其中直接控制台打印正在比较空的值数组反对布尔值(这将是错误的)

    let test = 'apple';
    if( test ){
      console.log( 'if/else: ' + true );
    }else{
      console.log( 'if/else: ' + false );
    }
    
    console.log( 'log: ' + ( test == true ) );

    【讨论】:

      【解决方案3】:

      这两个 sn-ps 实际上在做不同的事情,因此结果不同。

      第一个以[] 作为if 语句的条件,将数组强制转换为布尔值。 (if,很自然,只适用于布尔值,如果给定的值还不是布尔值,JS 会很高兴地转换它。)这会产生true - JS 中的所有对象都是“真实的”,其中包括所有数组。

      对于第二个 sn-p,您使用的是“松散相等”运算符 == - JS 规范为此提供了一组规则,用于将值转换为其他类型,最终在两者之间进行直接比较相同类型的值。在这种情况下,您可能希望或希望将非布尔值与truefalse 进行比较,从而将非布尔值强制为布尔值——但这不是发生的情况。规范所说的是,首先将布尔值强制转换为数值 - 导致true1(和false0)。所以它减少到[] == 1 - 这将在产生false 结果之前经历更多的转换。

      关键是在第二种情况下不会发生布尔转换。如果你认为这很愚蠢,那你可能是对的。这有点棘手,也是许多指南告诉您永远不要在 JS 中使用 == 的原因之一。一般来说,我实际上并不同意该建议(并且讨厌 linter 告诉我在任何情况下始终使用 ===) - 但你必须意识到一些危险。使用== 将值与truefalse 进行比较是总是 避免的。

      幸运的是,如果您想测试 x 是真还是假,您有一个非常简短且易于理解的方法 - 您在此处的第一个 sn-p 中使用的方法:if (x)

      【讨论】:

        【解决方案4】:

        [编辑] 所以我最初的答案令人困惑,你在互联网上找到的关于这个主题的许多答案存在一些不一致;所以,让我再试一次:

        第 1 部分:它们为何不同

        if([])if([] == true) 不是同一个操作。如果你看到下面的例子,你会在做同样的操作时得到同样的结果。

        //Output: false
        if([] == true) {
            console.log(true);
        } else{
            console.log(false);
        }
        
        //Output: false
        console.log([] == true);
        

        第 2 部分:为什么重要又名:令人困惑的部分

        在JS中,下面是一个常用的表达式,用来查看一个对象/变量是否存在:

        var foo = "Hello World";
        if (foo) ...
        

        从设计的角度来看,这个测试并不重要看foo是否等于真或假,它是一个看程序是否能找到对象或变量foo的测试。如果它找到 foo,那么它会在“then”条件下执行结果,否则会得到“else”条件。因此,在这种情况下,它将 foo 转换为 false for 不存在或 true for 确实存在。所以在这种情况下,字符串被简化为布尔值。

        相比之下:

        var foo = "Hello World";
        if (foo == true) ...
        

        通常试图找出 foo 的值是否实际上等于 true。在本例中,您将 foo "Hello World" 的值与布尔值进行比较,因此在本例中,"Hello World" 不等于 true。

        就像 foo 一样,[] 可以用不止一种方式计算。一个空数组仍然是一个对象;因此,在第一种情况下,它强制为真,因为它想知道是否可以找到 [];但是,[] 也等于 ['']。所以现在想象一下:

        if (['bar'] == 'bar') ...
        

        在这种情况下,JS 不会查看 ['bar'] 以查看它是否存在,而是作为一个包含单个值的对象,它可以将其转换为字符串 'bar'。

        所以:

        if([]); // is true because it is an object test that evaluates as (1 === 1)
        

        if([] == true) // is false because it is a string test that evaluates as ('' == 1) to (0 === 1)
        

        【讨论】:

        • 我不明白您的解释中的“响应”是什么意思。 JavaScript 语言中没有这样的概念。 if([]) 不检查“您是否收到回复”。 if 检查它传递的值是true 还是false。如果传递的值不是布尔值,则首先将其转换为布尔值。
        • 一个 IF 语句总是返回 true 或 false 含义 IF() {} ELSE{ }; IF 语句调用的过程本身就是一个布尔运算。当您只是在没有任何运算符(例如 IF(myVariable){...} 的情况下对变量/对象/等执行 IF 语句时,那么您不是在检查 myVariable 等于什么,而是在检查它是否存在。在这种情况下 [] 确实存在,但是作为一个空数组,所以 IF 返回 true
        • 我很困惑。首先你说if 检查真假,然后你说它检查“它是否存在”。 “那么您不是在检查 myVariable 等于什么,而是在检查它是否存在。” “它”是什么? if 不检查变量它检查值。变量只是值的容器。每个值都“存在”。 if(foo)if(Boolean(foo) === true) 相同。 "在这种情况下[]确实存在,但是作为一个空数组,所以IF返回true" 数组是否为空无关紧要。每个转换为布尔值的对象都是true,这就是为什么if([])true
        • 好的,进一步研究,是的,if(Boolean(foo) === true) 的思路是正确的。在大多数正常用例中,检查是否存在类似于 if(myVar) 并强制执行 if(1 === 1) 或 if(0 === 1) 逻辑上的真假语句。因此,正如您所说, [] 转换为 1 而不是 0 因为它是一个对象。 JS 不是在寻找对象的值,因为对象可以靠近任何东西,它只是在寻找它是否存在。所以我们说的是同一件事,但我认为是从不同的角度来看的。
        • [] 在与布尔值比较时转换为 0。如果您转换为布尔值,那么它不会转换为数字而是true
        猜你喜欢
        • 2017-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-12
        • 2013-11-18
        • 1970-01-01
        • 2013-01-14
        • 1970-01-01
        相关资源
        最近更新 更多