Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 空数组似乎同时等于true和false_Javascript - Fatal编程技术网

Javascript 空数组似乎同时等于true和false

Javascript 空数组似乎同时等于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值

空数组为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
值。在内部,调用了
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