在JS中短路空数组有一个意想不到的结果:`[] || true == []`

Dan*_*ski 5 javascript

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

var $holidayExpandBarOrOpeningHours = 
                $(".expandBar + .holidayHours_c").prev() || $(".openingHours"); 
Run Code Online (Sandbox Code Playgroud)

但令我惊讶的是,如果我们使用true语句短路空数组,仍然会返回一个空数组.我将在下面演示一些控制台代码,我的问题是为什么[] || true评估[].

false || "expected"
"expected"
false == []
true
[] || "expected"
[]
typeof([])
"object"
({}) || "expected"
Object {}
({}) == false
false
{} == false
SyntaxError: Unexpected token ==
Run Code Online (Sandbox Code Playgroud)

我的一部分认为这是因为一个数组是一个object评估为真的数组,但是如果是这样的话,那么基于({}) == true一个人的期望[] == true.

最后我要注意的是使用use 'strict'模式时结果是一样的.

Joh*_*ica 6

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

> !![]
true
> ![]
false
Run Code Online (Sandbox Code Playgroud)

当转换为数字时,[]为0.这就是为什么将它与false相比较返回true:当比较不同类型的两个值时,JavaScript首先将两者都转换为数字然后比较数字.

> +[]
0
> +false
0
> +[] == +false
true
Run Code Online (Sandbox Code Playgroud)


use*_*740 4

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

逻辑或使用ToBoolean,而等于使用ToNumber/ ToPrimitive


11.11 二元逻辑运算符开始:

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

由于ToBoolean([])为 true,[] || x结果为[]。这也是为什么if([]) { /* this runs */ }:JavaScript 中的数组是“真实”值

来自11.9.3 抽象相等比较算法

7) 如果 Type(y) 为 Boolean,则返回比较结果 x == ToNumber(y)

9) [..then] 如果 Type(x) 是 Object 并且 Type(y) 是 String 或 Number,则返回ToPrimitive(x) == y的比较结果。

5) [..then] 如果 Type(x) 为 String,Type(y) 为 Number,则返回ToNumber(x) == y的比较结果。

适用的逻辑[] == trueToNumber(ToPrimitive([])) == ToNumber(true).


以及转换值:

  • ToBoolean([])是真的
  • ToNumber(true)是 1
  • ToPrimitive([])是一个字符串(来自DefaultValue/toString

所以:

ToNumber(ToPrimitive([])) == ToNumber(true)
ToNumber("") == 1
0 == 1
false
Run Code Online (Sandbox Code Playgroud)

(约翰·库格曼所说的话实在是太长了。)


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

在默认环境下,ToPrimtive({})返回一个非空字符串(即"[object Object]"按照Object.prototype.toString)。ToNumber此字符串将在以下情况后计算为 NaN NaN == 1;或假。

请参阅为什么空数组类型会转换为零?+[]了解有关 ToPrimitive 转换的更多详细信息。