Javascript 短路JS中的空数组会产生意外结果:`[]| | true==[]`

Javascript 短路JS中的空数组会产生意外结果:`[]| | true==[]`,javascript,Javascript,在我的代码中,我假设以下短路是安全的: var $holidayExpandBarOrOpeningHours = $(".expandBar + .holidayHours_c").prev() || $(".openingHours"); 但令我惊讶的是,如果我们用true语句短路一个空数组,仍然会返回一个空数组。我将在下面用一些控制台代码进行演示,我的问题是为什么[]| | true的计算结果为[] false || "expected" "expec

在我的代码中,我假设以下短路是安全的:

var $holidayExpandBarOrOpeningHours = 
                $(".expandBar + .holidayHours_c").prev() || $(".openingHours"); 
但令我惊讶的是,如果我们用true语句短路一个空数组,仍然会返回一个空数组。我将在下面用一些控制台代码进行演示,我的问题是为什么
[]| | true
的计算结果为
[]

false || "expected"
"expected"
false == []
true
[] || "expected"
[]
typeof([])
"object"
({}) || "expected"
Object {}
({}) == false
false
{} == false
SyntaxError: Unexpected token ==
我的一部分认为这是因为数组是一个计算结果为true的
对象,但是如果是这样的话,那么基于
({})=true的
[]==true
人们会期望
[]==true


最后我想指出的是,使用
use'strict'
模式时,结果是相同的

空数组是一个对象;强制为布尔值的对象是
true
。所以

({}) || true; // -> {}
[] || true; // -> []
"" || true; // -> true (empty strings are coerced to false)

旁注-需要使用
{}
周围的括号来避免将其作为块进行分析。

这是因为
|
和使用
=
不同的转换规则

逻辑or使用,而等式等于使用/
ToPrimitive


发件人:

3) 如果ToBoolean(lval)为true,则返回lval

由于
ToBoolean([])
是真的,
[]| | x
导致
[]
。这也是为什么
如果([]){/*这运行*/}
:JavaScript中的数组是空的

发件人:

7) 如果类型(y)是布尔值,则返回比较结果x==ToNumber(y)

9) […然后]如果类型(x)是对象,类型(y)是字符串或数字, 返回比较结果ToPrimitive(x)==y

5) […然后]如果类型(x)是字符串,类型(y)是数字, 将比较结果返回到数字(x)=y

应用于
[]==true
的逻辑是
ToNumber(ToPrimitive([])==ToNumber(true)


以及转换值:

  • ToBoolean([])
    为真
  • ToNumber(true)
    为1
  • ToPrimitive([])
    是一个空字符串(from
    DefaultValue/toString
因此:

ToNumber(ToPrimitive([])==ToNumber(true)
ToNumber(“”==1
0 == 1
假的
(要说出约翰·库格曼的话还有很长的路要走。)


另外,
({})=true
通常为false,并遵循与上述相同的转换

在默认环境下,
toprimitive({})
返回一个非空字符串(即,
“[object object]”
,根据)。该字符串将在
ToNumber
之后计算为NaN,这样
NaN==1
;或者是假的


有关TopPrimitive转换的更多详细信息,请参阅。

转换为布尔值时,
[]
为true

> !![]
true
> ![]
false
转换为数字时,
[]
为0。这就是为什么将其与false进行比较会返回true:当比较两个不同类型的值时,JavaScript首先将两者转换为数字,然后比较数字

> +[]
0
> +false
0
> +[] == +false
true

空数组不是falsy为了支持@rgthree所说的内容,文章中有一篇关于truthy/falsy值的简单文章,您可能会感兴趣。
({})=true
是false,正如
[]==true
是false一样。过程是一样的,谢谢你的回复;是的,我考虑过,但再次看到我的问题,因为
[]==false
不等于
({})=false
。请参阅@JohnKugelman的答案-
=
强制使用
数字,而不是
布尔值。是的,Javascript在这方面有点疯狂。我很难找到为什么数组(
x
)被转换成
=
中的数字。据我所知,这将是
ToPrimitive([])==ToNumber(true)
[通过
=
]的第7条规则,然后是第9条规则-那么
ToPrimitive([])==0
(可能通过另一个过程)?但是我不能支持它。@user2864740 ToPrimitive(
[]
)生成空字符串,然后第5步开始(x是字符串,y是数字),空的sting通过ToNumber转换为
0
。(第5步是因为:布尔值在第7步变成了一个数字,数组在第9步变成了一个字符串。)@apsillers谢谢,我也发现了这一点