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

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

空数组是真,但它们也等于false。


var arr = [];

console.log('Array:', arr);

if (arr) console.log("It's true!");

if (arr == false) console.log("It's false!");

if (arr && arr == false) console.log("...what??");

我想这是由于等式运算符所操作的隐式转换。

有人能解释幕后发生了什么吗?


肥皂起泡泡
浏览 416回答 3
3回答

炎炎设计

你在这里测试不同的东西。if (arr)调用对象(Array是JS中对象的实例)将检查对象是否存在,并返回true/false。当你打电话if (arr == false)你比较价值这个物体和原语false价值。在内部,arr.toString()调用,它返回空字符串。"".这是因为toString调用数组返回Array.join()空字符串是JavaScript中的假值之一。

一只名叫tom的猫

关于这一行:if (arr == false) console.log("It's false!");也许这些会有帮助:console.log(0 == false) // trueconsole.log([] == 0) // trueconsole.log([] == "") // true我认为正在发生的是布尔值false被迫0用于与物体(左手边)进行比较。对象被强制为字符串(空字符串)。然后,空字符串也被胁迫成一个数字,即零。所以最后的比较是0 == 0,也就是true.编辑:看见规范的这一部分有关此操作的详细信息。下面是正在发生的事情,从规则1开始:1.如果类型(X)与类型(Y)不同,则转到步骤14。下一个适用的规则是#19:19.如果类型(Y)是布尔型,则返回比较x=ToNumber(Y)的结果。结果ToNumber(false)是0,我们现在有:[] == 0同样,规则1告诉我们跳到第14步,但实际适用的下一步是#21:21.如果Type(X)是Object,Type(Y)是字符串或数字,则返回比较ToPrimitive(X)=y的结果。结果ToPrimitive([])是空字符串,所以我们现在有:"" == 0同样,规则#1告诉我们跳到步骤#14,但实际适用的下一步是#17:17.如果Type(X)是String,Type(Y)是Number,则返回比较ToNumber(X)=y的结果。结果ToNumber("")是0,这就给我们留下了:0 == 0现在,这两个值都具有相同的类型,因此这些步骤从#1一直持续到#7,如下所示:7.如果x是与y相同的数字值,则返回true。所以,我们回来true.简言之:ToNumber(ToPrimitive([])) == ToNumber(false)

红颜莎娜

解释为什么ToPrimitive([])回报""对于“为什么”这个问题,有两种可能的答案是值得考虑的。第一种回答是:“因为规范上说这就是JavaScript的行为方式。”在ES5规范中,第9.1节,它将ToPrimitive的结果描述为对象的默认值:对象的默认值是通过调用对象的[DefaultValue]内部方法来检索的,并传递可选的提示PreferredType。第8.12.8节描述[[DefaultValue]]方法。此方法以“提示”作为参数,提示可以是字符串,也可以是数字。若要简化此事项,请不要使用某些细节,如果提示为字符串,则[[DefaultValue]]返回toString()如果存在并返回原语值,则返回valueOf()..如果提示为数字,则toString()和valueOf()是相反的,所以valueOf()首先调用,如果它是原语,则返回它的值。因此,是否[[DefaultValue]]返回toString()或valueOf()取决于对象的指定PreferredType以及这些函数是否返回原语值。默认valueOf()对象方法只返回对象本身,这意味着除非类重写默认方法,valueOf()只返回对象本身。情况就是这样Array.&nbsp;[].valueOf()返回对象[]本身。因为Array对象不是原语,[[DefaultValue]]提示无关:数组的返回值将是toString().引用大卫弗拉纳根JavaScript:权威指南顺便说一句,这是一本很棒的书,每个人都应该首先找到这些问题的答案:此对象到数字转换的详细信息解释了为什么空数组转换为数字0,以及为什么具有单个元素的数组也可以转换为数字。数组继承了返回对象而不是原始值的默认值()方法,因此数组到数字的转换依赖于toString()方法。空数组转换为空字符串。空字符串转换为数字0。具有单个元素的数组将转换为与一个元素相同的字符串。如果数组包含单个数字,则将该数字转换为字符串,然后返回到数字。对“为什么”问题的第二种回答,除了“因为规范说”,从设计的角度解释了为什么行为是有意义的。在这个问题上,我只能猜测。首先,如何将数组转换为数字?我能想到的唯一明智的可能性是将一个空数组转换为0,将任何非空数组转换为1,但正如韦恩的回答所揭示的,在许多类型的比较中,一个空数组将被转换为0。除此之外,很难为Array.value eOf()找到一个合理的原始返回值。因此,人们可能会说,这只是更有意义的Array.valueOf()是默认的,并返回Array本身,导致toString()是ToPrimitive使用的结果。将Array转换为字符串而不是数字更有意义。此外,正如弗拉纳根的引语所暗示的那样,这个设计决策确实允许某些类型的有益行为。例如:var&nbsp;a&nbsp;=&nbsp;[17],&nbsp;b&nbsp;=&nbsp;17,&nbsp;c=1;console.log(a==b);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;<=&nbsp;trueconsole.log(a==c);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;<=&nbsp;false此行为允许您将单个元素数组与数字进行比较,并获得预期的结果。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript