我正在尝试一个代码片段,console.log语句和条件语句中的空数组检查结果不同。帮助/思考为什么会有所不同?提前感谢!
//Output: true
if([]) {
console.log(true)
} else{
console.log(false)
}
//Output: false
console.log([] == true)
您似乎遇到了一个已知的JavaScript怪癖。
"[]是真的,但不是真的">
问题不在于你在哪里进行评估,而在于这两个看似相同的评估实际上是不同的。
请参阅https://github.com/denysdovhan/wtfjs#-是真的但不是真的
我的假设是,if/else块在其"真实"测试的一部分中,检查是否存在某种东西(而不仅仅是它是否为真(——其中直接控制台打印是将空数组的值与布尔值(这将是假的(进行比较
let test = 'apple';
if( test ){
console.log( 'if/else: ' + true );
}else{
console.log( 'if/else: ' + false );
}
console.log( 'log: ' + ( test == true ) );
这两个片段实际上在做不同的事情,因此产生了不同的结果。
第一种是将[]
作为if
语句的条件,将数组强制为布尔值。(当然,if
只适用于布尔值,如果给定的值还不是布尔值,JS会很乐意转换它。(这就产生了true
——JS中的所有对象都是"truthy",包括所有数组。
对于第二个片段,您使用的是"松散相等"运算符==
,JS规范为其提供了一组规则,用于如何将值转换为其他类型,最终实现同一类型的两个值之间的直接比较。在这种情况下,您可能希望将非布尔值与true
或false
进行比较,从而将非布尔型强制为布尔型,但事实并非如此。规范中所说的是,首先将布尔值强制为数值,从而为true
生成1
(为false
生成0
(。因此,它减少到[] == 1
——在得到false
结果之前,它将经历更多的转换。
关键是在第二种情况下不会发生布尔值的转换。如果你认为这很愚蠢,你可能是对的。这有点棘手,也是许多指南告诉您永远不要在JS中使用==
的原因之一。总的来说,我并不同意这个建议(我讨厌门楣告诉我在任何情况下都要使用===
(,但你必须意识到一些危险。使用==
将值与true
或false
进行比较是总是要避免的事情。
幸运的是,如果你想测试x
是真是假,你有一个非常简单易懂的方法来做它——你在这里的第一个片段中使用的方法:if (x)
[edit]所以我最初的答案令人困惑,你在互联网上找到的关于这个主题的许多答案都有一些不一致之处;那么,让我再试一次:
第1部分:它们不同的原因
if([](和if([]==true( 第2部分:为什么它很重要AKA:令人困惑的部分 在JS中,以下是一个常见的表达式,用于查看对象/变量是否存在: 从设计的角度来看,这个测试并不重要,看foo是否等于true或false,它是一个测试,看程序是否能找到对象或变量foo。如果它找到foo,那么它会在"then"条件下执行结果,否则会得到"else"条件。因此,在这种情况下,它将把foo转换为false表示不存在,或者true表示确实存在。因此,在这种情况下,字符串被简化为布尔值。 相比之下: 通常试图找出foo的值是否真的等于true。在这种情况下,您将foo"Hello World"的值与布尔值进行比较,因此在这种情况中,"Hello世界"不等于true。 就像foo一样,[]可以通过多种方式进行求值。空数组仍然是一个对象;因此,在第一种情况下,它强迫为真,因为它想知道[]是否可以被找到;但是,[]也等于['']。所以现在想象一下: 在这种情况下,JS不会查看['bar']是否存在,而是作为一个包含单个值的对象,可以将其转换为字符串'bar'。 因此: 和//Output: false
if([] == true) {
console.log(true);
} else{
console.log(false);
}
//Output: false
console.log([] == true);
var foo = "Hello World";
if (foo) ...
var foo = "Hello World";
if (foo == true) ...
if (['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)