There are two concepts which need to be considered here:
obj = new Boolean(false)
creates an Object, whose values is false
. The Object itself is considered truthy, it's value (which you get with toString()
or valueOf()
) of course is the boolean value false
.
(x||y)
returns the first truthy value (or if none are present, the last falsy value) and
(x&&y)
returns the first falsy value (or if none are present, the last truthy value).
So (obj||false)
returns your Boolean Object, (obj&&true)
returns the second (true
) value.
The further preceeding depends on the context of your expression.
"obj && true: " + (obj && true)
demands a string context, so toString()
is called on your Boolean Object, returning it's value which is false
(While the object itself is truthy!).
Furthermore,
(obj && true) == true
compares true == true
which of course is true. However,
(obj || true) == true
does a lot of type coercion §11.9.3 and compares
ToPrimitive(obj) == ToNumber(true)
(§9.1 and §9.3) which results in NaN == 1
which yields false.
The results get more predictable if you use the strict equality operator §11.9.6.