2

To see the result, open console in Google Chrome, do the following:

obj = new Boolean(false)
"obj && true: " + (obj && true)
"obj || true: " + (obj || false)

and:

(obj && true) == true   // this is true
(obj || false) == true   // this is false

and why

(obj || false)

returns the Boolean object, instead of a boolean value?

(hmm.. I also put a summary as answer below)

songyy
  • 4,323
  • 6
  • 41
  • 63

6 Answers6

3

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.

Christoph
  • 50,121
  • 21
  • 99
  • 128
2

For the first case, the obj is a truthy value so true && true returns true.

For the second case, it returns obj which is Boolean{}. If you then cast it to String (which happens, if you do "string" + (obj || false)), then it will return its value, which is "false".

Again, this is because the value of obj is false but the Object itself is a truthy value!

Willem Mulder
  • 12,974
  • 3
  • 37
  • 62
  • Thx for the reply. Why does (obj || false) return a Boolean object instead of a boolean value? – songyy May 14 '13 at 08:24
  • Because obj *is* a Boolean object, because you created it like that. If you want it otherwise, you should convert obj to a primitive boolean like 'obj = !!obj;' or have created obj as 'obj = false;' to start with. – Willem Mulder May 14 '13 at 08:27
  • IC. so the || operator is actually short-cast operator to return the first non-false value it sees. Thx a lot ;) – songyy May 14 '13 at 08:30
  • Completely correct! Glad to help. – Willem Mulder May 14 '13 at 08:31
1

In the first example your obj is evaluated as truthy and hence truthy && true == true.

In the second example, while evaluating the object is is again considered truthy and so the lazy evaluation stops after evaluating obj. Then obj is returned, which itself yields a value of false.

Sirko
  • 72,589
  • 19
  • 149
  • 183
0

Your object (obj) is a wrapped boolean, and JavaScript treats it that way.

(new Boolan(false) || false) is false indeed.

Andries
  • 1,547
  • 10
  • 29
0

my Chrome browser returns true for the former statement and returns a Boolean Object for the latter statement

0

After getting the answers below, let me do a summary here(People on StackOverFlow are really helpful~ Thank you all~):

The short-cut behavior of && and || operator, and the true value of object, is the root of the problem here I guess.

(the below are what I summarized from several behaviors I tried)

I would use:

o = new Object;
t = new Boolean(true);
f = new Boolean(false);

When || is used, it would take the first non-false value. Because:

(f || t) == true; // false
(t || f) == true; // true
(false || f) == true; // false
typeof (false || f);  // "object"
typeof (true || f);   // "boolean"

When && is used, it would take the first non-true value. Since objects are by-nature to be true, it would try to return the last occurring object, or the first false if there's.

Here's an example:

(o || t) // it returns the 'o' since it's the first true
(o && t) // it returns t since it's the last true
(true && t) // it returns t also, same reason
(false && t) // it returns false since it's the first occurring false.
songyy
  • 4,323
  • 6
  • 41
  • 63