在 JS 中短路空数组会产生意外结果:“[] ||真 == []'
Short-circuiting an empty array in JS has an unexpected outcome: `[] || true == []`
在我的代码中,我假设以下短路||
是安全的:
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 的object
,但是如果是这种情况,那么基于人们期望({}) == true
[] == true
。
最后我想指出的是,使用use 'strict'
模式时结果是相同的。
转换为布尔值时,[]
为真。
> !![]
true
> ![]
false
转换为数字时,[]
为 0。这就是为什么将其与 false 进行比较返回 true 的原因:当比较两个不同类型的值时,JavaScript 首先将两者转换为数字,然后比较数字。
> +[]
0
> +false
0
> +[] == +false
true
这是因为||
和使用==
不同的转换规则。
逻辑或使用ToBoolean
而相等使用ToNumber
/ToPrimitive
。
从 11.11 二进制逻辑运算符:
3) 如果 ToBoolean(lval) 为真,则返回 lval。
由于ToBoolean([])
为真,因此[] || x
会导致[]
。这也是为什么 JavaScript 中的 if([]) { /* this runs */ }
: 数组是"真实"值。
从 11.9.3 抽象相等比较算法
:7) 如果 Type(y) 是布尔值,则返回比较结果 x == ToNumber(y)。
9) [..then] 如果 Type(x) 是 Object 且 Type(y) 是 String 或 Number, 返回比较 ToPrimitive(x) == y 的结果。
5) [..则] 如果 Type(x) 是字符串,Type(y) 是 Number, 返回比较结果 ToNumber(x) == y。
应用于[] == true
的逻辑是ToNumber(ToPrimitive([])) == ToNumber(true)
。
转化价值:
-
ToBoolean([])
是真的 -
ToNumber(true)
为 1 -
ToPrimitive([])
是一个空字符串(来自DefaultValue/toString
)
所以:
ToNumber(ToPrimitive([])) == ToNumber(true)
ToNumber("") == 1
0 == 1
false
(要说约翰·库格尔曼的话,这还有很长的路要走。
此外,({}) == true
通常是假的,并且遵循与上述相同的转换。
在默认环境下,ToPrimtive({})
返回一个非空字符串(即 "[object Object]"
根据 Object.prototype.toString)。此字符串将在ToNumber
后计算为 NaN,以便NaN == 1
;或假。
请参阅为什么空数组类型转换为零?+[] 了解有关 ToPrimitive 转换的更多详细信息。
空数组是一个对象;强制转换为布尔值的对象true
。所以
({}) || true; // -> {}
[] || true; // -> []
"" || true; // -> true (empty strings are coerced to false)
旁注 - 需要{}
周围的括号以避免将其解析为块。
- 奇怪的Javascript结果
- Javascript(jQuery)给了我奇怪的结果
- 三元对短路
- JSONP请求返回结果,但也触发error_callback
- 如何在chrome扩展中存储数据/结果,以及如何使用setTimeout使其只被调用一次
- Javascript,输出结果后页面不断刷新
- 这是使用html快照和谷歌获取的预期结果吗?SEO/SPA
- 将地理编码结果转换为php变量以发布到mysql数据库
- AngularJS/HTML/Bootstrap元素用于动态搜索结果
- JQuery:向多个匹配结果添加换行符的最简单方法
- 当查询不在displayField中时,引导Ajax Typeahead不显示结果
- webpack代码拆分了handlerbs文件——结果是文件很大
- JavaScript循环无法正确计算/显示结果
- 相同的RegExp返回不同的结果-第一次是正确的结果,第二次是null
- Node.js使用Series函数(模式?)实现流控制时出现意外结果
- 试图将onChange函数作为道具传递给GrandChlidren,结果是TypeError:这是未定义的
- jQuery使用api获取typeform结果
- 根据条件检查数据库结果
- 什么'这是从第三个函数上的async 1st函数获得结果的更好方法
- 在 JS 中短路空数组会产生意外结果:“[] ||真 == []'