空数组为真,但也等于假。
Var arr = []; console.log(数组:,arr); if (arr) console.log("这是真的!"); if (arr == false) console.log("这是假的!"); 如果(arr & & arr = = false) console.log(“……什么? ?”);
我猜这是由于由等式运算符进行的隐式转换。
有人能解释一下幕后发生了什么吗?
空数组为真,但也等于假。
Var arr = []; console.log(数组:,arr); if (arr) console.log("这是真的!"); if (arr == false) console.log("这是假的!"); 如果(arr & & arr = = false) console.log(“……什么? ?”);
我猜这是由于由等式运算符进行的隐式转换。
有人能解释一下幕后发生了什么吗?
当前回答
例子:
const array = []
const boolValueOfArray = !!array // true
它的发生是因为
ToNumber(ToPrimitive([])) == ToNumber(false)
[]为空数组对象→ToPrimitive([])→""→ToNumber("")→0 tonnumber (false)→0 0 == 0→true
其他回答
关于台词:
if (arr == false) console.log("It's false!");
下面这些也许会有所帮助:
console.log(0 == false) // true
console.log([] == 0) // true
console.log([] == "") // true
我相信发生的是布尔值false被强制为0,以便与对象(左侧)进行比较。对象被强制转换为字符串(空字符串)。然后,空字符串也被强制转换为一个数字,即零。所以最后的比较结果是0 == 0,这是正确的。
编辑:请参阅规范的这一部分,以了解具体的工作原理。
从规则1开始,事情是这样的:
1. 如果“Type(x)”和“Type(y)”不一致,执行步骤14。
下一个适用的规则是第19条:
19. 如果Type(y)是Boolean,返回比较的结果x == 当时(y)。
ToNumber(false)的结果是0,所以我们现在有:
[] == 0
同样,规则1告诉我们跳转到步骤14,但实际应用的下一步是#21:
21. 如果类型(x)是对象,类型(y)是字符串或数字,则返回 对比结果 ToPrimitive (x) = = y。
ToPrimitive([])的结果是空字符串,所以我们现在有:
"" == 0
同样,规则1告诉我们跳转到步骤14,但实际应用的下一步是#17:
17. 如果Type(x)是String且Type(y)是Number,则返回 number (x)== y。
ToNumber("")的结果是0,剩下的是:
0 == 0
现在,两个值具有相同的类型,因此步骤从#1继续到#7,即:
7. 如果x与y的数值相同,则返回true。
因此,我们返回true。
简而言之:
ToNumber(ToPrimitive([])) == ToNumber(false)
你在这里测试不同的东西。
if (arr)调用对象(数组是对象在JS中的实例)将检查对象是否存在,并返回true/false。
当你调用if (arr == false)时,你比较这个对象的值和原始的false值。在内部,调用了arr.toString(),它返回一个空字符串“”。
这是因为在Array上调用toString会返回Array.join(),而空字符串是JavaScript中的一个假值。
当我尝试使用knockout.js映射插件时,上述方法都没有帮助我,也许是因为“空数组”并不是真的空。
我最终使用:data-bind="if: arr()。长度”,这就成功了。
这是专门针对knockout的,不是OP的问题,但也许它会帮助其他在类似情况下浏览这里的人。
在if (arr)中,如果arr是一个对象,它总是被求值(ToBoolean)为true,因为JavaScript中的所有对象都是true。(null不是一个对象!)
[] == false采用迭代法求值。首先,如果==的一边是原语,另一边是object,它首先将object转换为原语,然后如果两边都不是字符串,则将两边都转换为Number(如果两边都是字符串,则使用字符串比较)。因此,比较是这样迭代的,[]== false -> " == false -> 0 == 0 -> true。
似乎没有人谈论原因 (arr && arr == false)为真。只是为了不确定运算符优先级的人,根据MDN, ==的优先级高于&&,所以它实际上是(arr && (arr == false))。在通配符的答案之后,它是真&&真,所以它是真。
Var arr = []; 如果(arr & & arr = = false) console.log(“……什么? ?”);