为什么空的 JavaScript 数组在条件结构中的计算结果为 true

Why do empty JavaScript arrays evaluate to true in conditional structures?

本文关键字:计算 结果 true 结构 条件 JavaScript 数组 为什么      更新时间:2023-09-26

我在代码中遇到了很多错误,因为我期望这个表达式:

Boolean([]);评估为假。

但事实并非如此

,因为它被评估为真实。

因此,可能返回的函数[]如下所示:

// Where myCollection possibly returned [ obj1, obj2, obj3] or []
if (myCollection)
{
  // ...
} else
{
  // ...
}

没有做预期的事情。

我是否错误地假设[]一个空数组的计算结果应该为 false?

另外,此行为在所有浏览器中是否一致?还是那里也有陷阱?顺便说一下,我在谷歌浏览器中观察到了这种行为。

来自 http://www.sitepoint.com/javascript-truthy-falsy/

以下值始终是假的:

  • 0(零(
  • 0n (BigInt zero(
  • "(空字符串(
  • 定义
  • NaN(一个特殊的数字值,意思是不是数字!

所有其他值都是真值,包括"0"(引号中的零(、"false"(引号中的假(、空函数、空数组 ([] ( 和空对象 ( {} (。

关于为什么会这样,我怀疑这是因为JavaScript数组只是一种特定类型的对象。特别处理阵列需要额外的开销来测试Array.isArray()。此外,如果在这种情况下,真正的数组的行为与其他类似数组的对象不同,可能会令人困惑,而使所有类似数组的对象的行为相同会更加昂贵。

您应该检查该数组的.length以查看它是否包含任何元素。

if (myCollection) // always true
if (myCollection.length) // always true when array has elements
if (myCollection.length === 0) // same as is_empty(myCollection)

虽然[]等于false,但它的计算结果为true

是的,这听起来很糟糕,或者至少有点令人困惑。看看这个:

const arr = [];
if (arr) console.log("[] is truethy");
if (arr == false) console.log("however, [] == false");

在实践中,如果你想检查某物是否为空,然后检查length。(?.运算符确保也涵盖null

const arr = []; // or null;
if (!arr?.length) console.log("empty or null")

[]==false  // returns true

由于 ECMA 规范 #Section 11.9.3 中提到的抽象相等算法,因此计算结果为 true。

如果你通过算法运行,上面提到。

第一次迭代中,满足的条件是,

Step 7: If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

因此,上述条件转换为 -> [] == 0

现在在第二次迭代中,满足的条件[] == 0

Step 9: If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.

[] 是一个对象,从此以后,在转换为基元时,它会转换为空字符串''

因此,上述条件转换为 -> '' == 0

第三次迭代中,满足的条件为:

Step 5: If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.

众所周知,空字符串''是一个falsy值,因此将空字符串转换为数字将返回一个值0 .

从此以后,我们的状况将转变为-> 0 == 0

第四次迭代中,满足第一个条件,其中类型相等且数字相等。

从此以后,[] == false的最终值减少到0 == 0这是真的。

希望这能回答你的问题。否则,您也可以参考此youtube视频

我怀疑这与离散数学和条件(如果当时(的工作方式有关。条件有两个部分,但是在第一部分不存在的情况下,无论第二部分如何,它都会返回称为空洞真理的东西。

这是维基百科页面中空洞真理的例子

"当房间里

没有手机时,"房间里的所有手机都关机"的说法是正确的。在这种情况下,"房间里的所有手机都打开了"的说法也是空洞的。

维基百科甚至在稍后特别提到了JavaScript。

https://en.wikipedia.org/wiki/Vacuous_truth#:~:text=In%20mathematics%20and%20logic%2C%20a,the%20antecedent%20cannot%20be%20satisfied.&text=One%20example%20of%20such%20a,Eiffel%20Tower%20is%20in%20Bolivia%22。

还想补充一点,JavaScript 中的所有对象(数组也是对象(都作为链接存储在内存中,并且这些链接始终不为 null 或零,这就是为什么 Boolean({}) === trueBoolean([]) === true .

这也是为什么相同的对象(按值而不是链接复制(总是不相等的原因。

{} == {} // false
let a = {};
let b = a; // copying by link
b == a // true

就像在JavaScript中一样,一切都是一个对象,所以对于虚假和空,我使用以下条件:

if(value && Object.keys(value).length){
    // Not falsy and not empty
}
else{
    // falsy or empty array/object
}

在 JavaScript 中,空字符串和空数组都被视为假值。在布尔上下文中评估时,它们被视为 false。在这方面似乎可能会有一些混淆。

澄清一下,在 JavaScript 中,以下值被认为是错误的:

  1. false:布尔值为假。
  2. 0:数字零。
  3. NaN:非数字,表示无效或无法表示的值。
  4. null :表示有意缺少任何对象值。
  5. undefined :表示已声明但尚未赋值的变量。
  6. '' :空字符串。
  7. document.all :不再建议使用的历史神器。

布尔上下文中(例如在 if 语句或条件表达式中(遇到这些值时,这些值被强制为 false。

现在,值得注意的是,空数组[]仍然是有效的 JavaScript 对象,并且被视为真实值。但是,当在布尔上下文中使用时,例如在 if 语句中,空数组会自动强制转换为其布尔表示形式,这是假的。

例如:

if ([]){
  console.log("This will not be executed.");
}
if (''){
  console.log("This will not be executed either.");
}
if (0){
  console.log("Nor this.");
}
if (null){
  console.log("Neither this.");
}
if (undefined){
  console.log("Or this.");
}

在上面的代码中,if块内的任何语句都不会被执行,因为括号内的所有值都被认为是假的。

因此,在 JavaScript 中,空字符串和空数组都是 falsey 值,这意味着在布尔上下文中计算时它们被视为 false。