在JS中短路空数组有一个意想不到的结果:`[] || true == []` [英] Short-circuiting an empty array in JS has an unexpected outcome: `[] || true == []`

查看:62
本文介绍了在JS中短路空数组有一个意想不到的结果:`[] || 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'模式。

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 ToNumber(ToPrimitive([]))== ToNumber(true)

转换价值:


  • ToBoolean([])为真

  • ToNumber(true)是1

  • ToPrimitive([])是一个字符串(来自 DefaultValue / toString

  • ToBoolean([]) is true
  • ToNumber(true) is 1
  • ToPrimitive([]) is an empty string (from DefaultValue/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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆