为啥空的 JavaScript 数组在条件结构中评估为真?

Posted

技术标签:

【中文标题】为啥空的 JavaScript 数组在条件结构中评估为真?【英文标题】:Why do empty JavaScript arrays evaluate to true in conditional structures?为什么空的 JavaScript 数组在条件结构中评估为真? 【发布时间】:2013-10-09 09:11:45 【问题描述】:

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

Boolean([]); 评估为假。

但事实并非如此,因为它评估为真。

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

// Where myCollection possibly returned [ obj1, obj2, obj3] or []
if(myCollection)

  // ...

else

  // ...

没有做预期的事情。

我假设 [] 是一个空数组是不是错了?

另外,这种行为在所有浏览器中是否一致?或者那里也有任何陷阱?顺便说一下,我在 Google Chrome 中观察到了这种行为。

【问题讨论】:

数组是对象,对象是真实的。只需询问array.length,如果不为零,它将是真实的。显式转换为布尔值时,数组先变成空字符串,然后空字符串变成false。 你为什么不用myCollection.length > 0 @Steve - 如果myCollection 恰好是nullundefined,这将不起作用。您需要使用if(myCollection && myCollection.length > 0) @TedHopp - 当然......我只是指出 myCollection.length > 0 提供了一个布尔值,它正在执行 OP 的要求......他仍然需要从那里完成工作。 javascript empty array seems to be true and false at the same time 的可能重复项 【参考方案1】:

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

以下值总是假的:

错误 0(零) “”(空字符串) 未定义 NaN(一个特殊的 Number 值,意思是 Not-a-Number!)

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

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

【讨论】:

如果您测试表达式[] == false,它的计算结果为true @m.rufca 见***.com/questions/5491605/… 在您发布的链接中,有一些表格使用== 比较器显示了意外情况。我评论只是为了在期待真假评估时要小心。 这并不能真正回答问题,这就是为什么。为什么空数组是真的,而空字符串是假的?作为一个深思熟虑的设计决定,这感觉很糟糕。 也许吧,因为它们需要像原始对象一样工作。但是 Javascript 没有原始数组。【参考方案2】:

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

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

【讨论】:

【参考方案3】:

虽然[] 等于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")

【讨论】:

哇,那个optional chaining operator ?.。这似乎很新(而且很有用)。感谢我的 TIL。 @КонстантинВан 我想它需要关于兼容性的警告。 :-) 感谢您指出这一点。 为什么我现在才知道可选链操作符?和相关的Nullish coalescing operator 太好了!谢谢【参考方案4】:

我怀疑这与离散数学和条件(如果那样)的工作方式有关。条件句有两部分,但在第一部分不存在的情况下,无论第二部分如何,它都会返回一个叫做空虚的事实的东西。

这是***页面中关于空洞事实的示例

“房间内所有手机均已关闭”语句在房间内没有手机时为真。在这种情况下,“房间内所有手机均已打开”语句也为空真的”

***稍后甚至特别提到了 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.

【讨论】:

【参考方案5】:

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

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

 ==  // false

let a = ;
let b = a; // copying by link
b == a // true

【讨论】:

【参考方案6】:

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

if(value && Object.keys(value).length)
    // Not falsy and not empty

else
    // falsy or empty array/object

【讨论】:

以上是关于为啥空的 JavaScript 数组在条件结构中评估为真?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 PATCH 请求的响应是空的? (Javascript)

为啥条件运算符不能正确地允许使用“null”来分配给可为空的类型? [复制]

为啥判断队列是不是为空时只需比较队首指示和队尾指示是不是相等即可?

谁能告诉我为啥我的过滤数组是空的?

JavaScript为啥用push方法为数组添加新的索引的时候,会出现这种情况?

javascript基础知识-数组-条件判断语句-逻辑操作符-选择结构语句-循环语句