Javascript 空数组似乎同时等于true和false
空数组为true,但也等于falseJavascript 空数组似乎同时等于true和false,javascript,Javascript,空数组为true,但也等于false var arr=[]; log('Array:',arr); if(arr)console.log(“这是真的!”); if(arr==false)console.log(“它是false!”); if(arr&&arr==false)console.log(“…什么?”)您正在测试不同的东西 if(arr)调用对象(数组是JS中对象的实例)将检查对象是否存在,并返回true/false 调用if(arr==false)时,比较此对象的值和原语false值
var arr=[];
log('Array:',arr);
if(arr)console.log(“这是真的!”);
if(arr==false)console.log(“它是false!”);
if(arr&&arr==false)console.log(“…什么?”)代码>您正在测试不同的东西
if(arr)
调用对象(数组是JS中对象的实例)将检查对象是否存在,并返回true/false
调用if(arr==false)
时,比较此对象的值和原语false
值。在内部,调用了arr.toString()
,它返回一个空字符串“”
这是因为在数组上调用的toString
返回Array.join()
,空字符串是JavaScript中的错误值之一。关于行:
if (arr == false) console.log("It's false!");
也许这些会有帮助:
console.log(0 == false) // true
console.log([] == 0) // true
console.log([] == "") // true
我认为正在发生的是布尔值false
被强制为0
,以便与对象(左侧)进行比较。对象被强制为字符串(空字符串)。然后,空字符串也被强制转换为一个数字,即零。最后的比较是0
==0
,这是true
编辑:请参阅,以获取有关此操作的详细信息
下面是发生的事情,从规则1开始:
一,。如果类型(x)与类型(y)不同,则转至步骤14
下一条规则是#19:
十九,。如果类型(y)为布尔值,则返回比较结果x==
汤姆伯(y)
ToNumber(false)
的结果是0
,因此我们现在有:
[] == 0
"" == 0
同样,规则1告诉我们跳到第14步,但下一步实际适用的是第21步:
二十一,。如果类型(x)是Object,类型(y)是String或Number,则返回
比较结果
ToPrimitive(x)=y
ToPrimitive([])
的结果是空字符串,因此我们现在有:
[] == 0
"" == 0
同样,规则1告诉我们跳到第14步,但下一步实际适用的是第17步:
十七,。如果类型(x)是字符串,类型(y)是数字,则返回
对数字(x)=y的比较
ToNumber(“”
的结果是0
,这给我们留下了:
0 == 0
现在,两个值的类型相同,因此步骤从#1继续到#7,即:
七,。如果x与y的数值相同,则返回true
因此,我们返回true
简言之:
ToNumber(ToPrimitive([])) == ToNumber(false)
当我尝试使用knockout.js映射插件时,以上这些都没有帮助,可能是因为“空数组”并不是真的空的
最后我使用了:data bind=“if:arr().length”
,这就成功了
这是专门针对淘汰赛的,不是OP的问题,但可能会帮助其他人在类似情况下浏览此处。在if(arr)中,如果arr是一个对象,则始终将其计算为true(ToBoolean),因为。(null不是对象!)
[]==false
采用迭代方法进行评估。首先,如果==
的一侧是基本体,另一侧是对象,则首先将对象转换为基本体,然后如果两侧都不是字符串,则将两侧转换为数字(如果两侧都是字符串,则使用字符串比较)。因此,重复比较就像,[]==false
->'==false
->0==0
->true
补充答案,并试图解释为什么ToPrimitive([])
返回,
,值得考虑两种可能的“为什么”问题答案。第一种类型的答案是:“因为规范说这就是JavaScript的行为。”在ES5规范中,它将ToPrimitive的结果描述为对象的默认值:
通过调用对象的[[DefaultValue]]内部方法并传递可选提示PreferredType,可以检索对象的默认值
描述[[DefaultValue]]
方法。此方法将“提示”作为参数,提示可以是字符串或数字。为了简化这一问题,可以省略一些细节,如果提示是字符串,则[[DefaultValue]]
返回toString()
的值(如果存在),并返回原语值,否则返回valueOf()
的值。如果提示是Number,则toString()
和valueOf()
的优先级将颠倒,以便首先调用valueOf()
,如果是原语,则返回其值。因此,[[DefaultValue]]
是否返回toString()
或valueOf()
的结果取决于为对象指定的PreferredType以及这些函数是否返回原语值
默认的valueOf()
对象方法只返回对象本身,这意味着除非类重写默认方法,valueOf()
只返回对象本身。数组的情况就是这样[].valueOf()
返回对象本身。由于数组
对象不是基元,因此[[DefaultValue]]
提示是不相关的:数组的返回值将是toString()的值。
顺便说一句,这本书是一本极好的书,应该是每个人首先得到这些问题答案的地方:
此对象到数字转换的详细信息解释了为什么空数组转换为数字0,以及为什么带有单个元素的数组也可以转换为数字。数组继承返回对象而不是基元值的默认valueOf()方法,因此数组到数字的转换依赖于toString()方法。空数组将转换为空字符串。空字符串将转换为数字0。具有单个元素的数组将转换为与该元素相同的字符串
ToNumber(ToPrimitive([])) == ToNumber(false)
console.log('-- types: undefined, boolean, number, string, object --');
console.log(typeof undefined); // undefined
console.log(typeof null); // object
console.log(typeof NaN); // number
console.log(typeof false); // boolean
console.log(typeof 0); // number
console.log(typeof ""); // string
console.log(typeof []); // object
console.log(typeof {}); // object
console.log('-- Different values: NotExist, Falsy, NaN, [], {} --');
console.log('-- 1. NotExist values: undefined, null have same value --');
console.log(undefined == null); // true
console.log('-- 2. Falsy values: false, 0, "" have same value --');
console.log(false == 0); // true
console.log(false == ""); // true
console.log(0 == ""); // true
console.log('-- 3. !NotExist, !Falsy, and !NaN return true --');
console.log(!undefined); // true
console.log(!null); // true
console.log(!false); // true
console.log(!""); // true
console.log(!0); // true
console.log(!NaN); // true
console.log('-- 4. [] is not falsy, but [] == false because [].toString() returns "" --');
console.log(false == []); // true
console.log([].toString()); // ""
console.log(![]); // false
console.log('-- 5. {} is not falsy, and {} != false, because {}.toString() returns "[object Object]" --');
console.log(false == {}); // false
console.log({}.toString()); // [object Object]
console.log(!{}); // false
console.log('-- Comparing --');
console.log('-- 1. string will be converted to number or NaN when comparing with a number, and "" will be converted to 0 --');
console.log(12 < "2"); // false
console.log("12" < "2"); // true
console.log("" < 2); // true
console.log('-- 2. NaN can not be compared with any value, even if NaN itself, always return false --');
console.log(NaN == NaN); // false
console.log(NaN == null); // false
console.log(NaN == undefined); // false
console.log(0 <= NaN); // false
console.log(0 >= NaN); // false
console.log(undefined <= NaN); // false
console.log(undefined >= NaN); // false
console.log(null <= NaN); // false
console.log(null >= NaN); // false
console.log(2 <= "2a"); // false, since "2a" is converted to NaN
console.log(2 >= "2a"); // false, since "2a" is converted to NaN
console.log('-- 3. undefined can only == null and == undefined, and can not do any other comparing even if <= undefined --');
console.log(undefined == null); // true
console.log(undefined == undefined); // true
console.log(undefined == ""); // false
console.log(undefined == false); // false
console.log(undefined <= undefined); // false
console.log(undefined <= null); // false
console.log(undefined >= null); // false
console.log(0 <= undefined); // false
console.log(0 >= undefined); // false
console.log('-- 4. null will be converted to "" when <, >, <=, >= comparing --');
console.log(12 <= null); // false
console.log(12 >= null); // true
console.log("12" <= null); // false
console.log("12" >= null); // true
console.log(0 == null); // false
console.log("" == null); // false
console.log('-- 5. object, including {}, [], will be call toString() when comparing --');
console.log(12 < {}); // false, since {}.toString() is "[object Object]", and then converted to NaN
console.log(12 > {}); // false, since {}.toString() is "[object Object]", and then converted to NaN
console.log("[a" < {}); // true, since {}.toString() is "[object Object]"
console.log("[a" > {}); // false, since {}.toString() is "[object Object]"
console.log(12 < []); // false, since {}.toString() is "", and then converted to 0
console.log(12 > []); // true, since {}.toString() is "", and then converted to 0
console.log("[a" < []); // false, since {}.toString() is ""
console.log("[a" > []); // true, since {}.toString() is ""
console.log('-- 6. According to 4 and 5, we can get below weird result: --');
console.log(null < []); // false
console.log(null > []); // false
console.log(null == []); // false
console.log(null <= []); // true
console.log(null >= []); // true
1. [] == false; // true, because an empty array has nothing to be truthy about
2. [2] == false; // false because it has at least 1 item
3. [false] == false; // also false because false is still an item
4. [[]] == false; // false, empty array is still an item
1. [] === false; // false, because an array (regardless of empty or not) is not strictly comparable to boolean `false`
2. [] === true; // false, same as above, cannot strictly compare [] to boolean `true`
3. [[]] === false; // true, because see #1