在JS中短路空数组有一个意想不到的结果:`[] || true == []` [英] Short-circuiting an empty array in JS has an unexpected outcome: `[] || true == []`
问题描述
在我的代码中,我假设以下 ||
短路是安全的:
In my code I assumed the following ||
short-circuiting was safe:
var $holidayExpandBarOrOpeningHours =
$(".expandBar + .holidayHours_c").prev() || $(".openingHours");
但令我惊讶的是,如果我们使用true语句短路空数组,那么空数组仍然是回。我将在下面演示一些控制台代码,我的问题是为什么 [] || true
评估为 []
。
But to my surprise if we short-circuit an empty array with a true statement an empty array is still returned. I will demonstrate with some console code below and my question is why [] || true
evaluates to []
.
false || "expected"
"expected"
false == []
true
[] || "expected"
[]
typeof([])
"object"
({}) || "expected"
Object {}
({}) == false
false
{} == false
SyntaxError: Unexpected token ==
部分我认为这是因为数组是对象
评估为true,但是如果是这种情况而不是基于({})== true
那么人们会期望 [] == true
。
Part of me thinks that it is because an array is an object
which evaluates to true, however if that was the case than based on ({}) == true
one would expect [] == true
.
我想要注意的最后一点是使用使用'strict'$ c时的结果是一样的$ c>模式。
Last thing I would like to note is the outcome is the same when using use 'strict'
mode.
推荐答案
这是因为 ||
并使用 ==
转换的规则。
This is because ||
and use ==
different rules for the conversion.
逻辑 - 或使用 ToBoolean
而等于等于使用 ToNumber
/ ToPrimitive
。
The logical-or uses ToBoolean
while the equality equals uses ToNumber
/ToPrimitive
.
来自 11.11二进制逻辑运算符:
3)如果 ToBoolean(lval)为true,返回lval。
3) If ToBoolean(lval) is true, return lval.
由于 ToBoolean([])
是真的, [] || x
结果为 []
。这也是 if([]){/ *这运行* /}
的原因:JavaScript中的数组是truthy值。
Since ToBoolean([])
is true, [] || x
results in []
. This is also why if([]) { /* this runs */ }
: arrays in JavaScript are "truthy" values.
来自 11.9.3抽象等式比较算法:
7)如果Type(y)是布尔值,则返回比较结果x == ToNumber(y)。
9)[ ..then]如果Type(x)是Object而Type(y)是String或Number,
返回比较结果 ToPrimitive(x) == y。
9) [..then] If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.
5)[..]如果Type(x)是String而Type(y)是Number,
返回比较结果 ToNumber(x ) == y。
5) [..then] If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
应用于 [] == true $的逻辑c $ c>是
ToNumber(ToPrimitive([]))== ToNumber(true)
。
转换价值:
-
ToBoolean([])
为真 -
ToNumber(true)
是1 -
ToPrimitive([])
是一个空字符串(来自DefaultValue / toString
)
ToBoolean([])
is trueToNumber(true)
is 1ToPrimitive([])
is an empty string (fromDefaultValue/toString
)
所以:
ToNumber(ToPrimitive([])) == ToNumber(true)
ToNumber("") == 1
0 == 1
false
(这是一个很长的路要说约翰什么库格尔曼说。)
(Which is a long way to say what John Kugelman said.)
此外,({})== true
通常是 false 并遵循与上述相同的转化。
Also, ({}) == true
is normally false and follows the same conversions as above.
在默认环境下, ToPrimtive({} )
返回一个非空字符串(即[object Object]
根据 Object.prototype.toString )。在 ToNumber
之后,此字符串将评估为NaN,以便 NaN == 1
;或者是假。
Under a default environment, ToPrimtive({})
returns a non-empty string (i.e. "[object Object]"
as per Object.prototype.toString). This string will evaluate to NaN after ToNumber
such that NaN == 1
; or false.
参见为什么空数组类型转换为零? + [] 了解有关ToPrimitive转化的更多详情。
See Why an empty Array type-converts to zero? +[] for more details on the ToPrimitive conversion.
这篇关于在JS中短路空数组有一个意想不到的结果:`[] || true == []`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!