最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Short-circuiting an empty array in JS has an unexpected outcome: `[] || true == []` - Stack Overflow

programmeradmin1浏览0评论

In my code I assumed the following || short-circuiting was safe:

var $holidayExpandBarOrOpeningHours = 
                $(".expandBar + .holidayHours_c").prev() || $(".openingHours"); 

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 ==

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.

Last thing I would like to note is the oute is the same when using use 'strict' mode.

In my code I assumed the following || short-circuiting was safe:

var $holidayExpandBarOrOpeningHours = 
                $(".expandBar + .holidayHours_c").prev() || $(".openingHours"); 

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 ==

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.

Last thing I would like to note is the oute is the same when using use 'strict' mode.

Share Improve this question asked Dec 18, 2013 at 21:32 Daniel SokolowskiDaniel Sokolowski 12.5k4 gold badges74 silver badges58 bronze badges 3
  • 2 An empty array is not falsy – rgthree Commented Dec 18, 2013 at 21:34
  • In support of what @rgthree said, this article has a simple write-up about truthy/falsy values that you may be interested in. – War10ck Commented Dec 18, 2013 at 21:37
  • ({}) == true is false, just as [] == true is false. The process is the same. – user2864740 Commented Dec 18, 2013 at 22:32
Add a ment  | 

3 Answers 3

Reset to default 6

When converted to a boolean value, [] is true.

> !![]
true
> ![]
false

When converted to a number, [] is 0. That's why paring it with false returns true: when paring two values of different types, JavaScript first converts both to numbers and then pares the numbers.

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

This is because || and use == different rules for the conversion.

The logical-or uses ToBoolean while the equality equals uses ToNumber/ToPrimitive.


From 11.11 Binary Logical Operators:

3) If ToBoolean(lval) is true, return lval.

Since ToBoolean([]) is true, [] || x results in []. This is also why if([]) { /* this runs */ }: arrays in JavaScript are "truthy" values.

From 11.9.3 The Abstract Equality Comparison Algorithm:

7) If Type(y) is Boolean, return the result of the parison x == ToNumber(y).

9) [..then] If Type(x) is Object and Type(y) is either String or Number, return the result of the parison ToPrimitive(x) == y.

5) [..then] If Type(x) is String and Type(y) is Number, return the result of the parison ToNumber(x) == y.

The logic applied to [] == true is ToNumber(ToPrimitive([])) == ToNumber(true).


And the conversion values:

  • ToBoolean([]) is true
  • ToNumber(true) is 1
  • ToPrimitive([]) is an empty string (from DefaultValue/toString)

So:

ToNumber(ToPrimitive([])) == ToNumber(true)
ToNumber("") == 1
0 == 1
false

(Which is a long way to say what John Kugelman said.)


Also, ({}) == true is normally false and follows the same conversions as above.

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.

See Why an empty Array type-converts to zero? +[] for more details on the ToPrimitive conversion.

An empty array is an object; objects coerced to booleans are true. So

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

Sidenote - the parentheses around {} are required to avoid parsing it as a block.

发布评论

评论列表(0)

  1. 暂无评论