为什么空的 JavaScript 数组在条件结构中的计算结果为 true
Why do empty JavaScript arrays evaluate to true in conditional structures?
我在代码中遇到了很多错误,因为我期望这个表达式:
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({}) === true
, Boolean([]) === 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 中,以下值被认为是错误的:
-
false
:布尔值为假。 -
0
:数字零。 -
NaN
:非数字,表示无效或无法表示的值。 -
null
:表示有意缺少任何对象值。 -
undefined
:表示已声明但尚未赋值的变量。 -
''
:空字符串。 -
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。
- if(foo!==null)的计算结果为true,即使foo为null
- ngIf的计算结果始终为true
- 设置为负数的变量计算结果为true
- 如何在模态助推器中显示计算结果(JS)
- 将javascript计算结果自动放入HTML表单中
- JavaScript/jQuery:格式化日期计算结果的最佳方式
- 使用AngularJS从服务器获取计算结果
- 如果ng-if的计算结果为false,AngularJS会使我的模型数据无效
- 计算结果Javascript中不同数字的数量
- javascript/html获胜't显示计算结果
- 使正数的计算结果为真,使负数计算为假
- Javascript 无法计算结果
- 为什么 {} == false 的计算结果为 false,而 [] == false 的计算结果为 true
- 以 HTML 格式显示计算结果 (javascript)
- 如果 x = 3 且 z 未分配,为什么 z = x-- - --x 的计算结果为 2
- 为什么 _=$=+[],++_+''+$ 的计算结果为 10
- 如何使用 ng-class 在值计算结果为零时删除类
- 为什么Number.MIN_VALUE < -1219312(或任何小值)的计算结果为 false
- 为什么空的 JavaScript 数组在条件结构中的计算结果为 true
- JavaScript 中的计算结果与 Java 中的计算结果不同