Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is (condition == !condition) true in JavaScript? [duplicate]

Tags:

javascript

Exactly why does the condition here evaluate to true?

var condition = new Boolean(false); if (condition == !condition)     alert("The more you know..."); 
like image 549
user541686 Avatar asked Aug 06 '13 03:08

user541686


People also ask

Can you have multiple if statements in JavaScript?

You can have as many else if statements as necessary. In the case of many else if statements, the switch statement might be preferred for readability. As an example of multiple else if statements, we can create a grading app that will output a letter grade based on a score out of 100.

What does if true mean in JavaScript?

This looks like a debugging statement left in. if(true) This is always true, so you could remove the test entirely and just run with the true statement. Follow this answer to receive notifications.

How to write condition in JavaScript?

In JavaScript we have the following conditional statements: Use if to specify a block of code to be executed, if a specified condition is true. Use else to specify a block of code to be executed, if the same condition is false. Use else if to specify a new condition to test, if the first condition is false.


2 Answers

Break it down:

var condition = new Boolean(false); 

This is actually an object, and condition.valueOf() === false

!{} evaluates to false since {} is true (explained http://www.ecma-international.org/ecma-262/5.1/#sec-9.2)

So the check is condition.valueOf() == false, which is true

like image 88
SheetJS Avatar answered Oct 05 '22 17:10

SheetJS


You're comparing an object (LHS) to the boolean false (RHS).

[object Boolean] == false 

The == operator performs type coercion according to the Abstract Equality Comparison Algorithm defined by ECMAScript. 11.9.3 The Abstract Equality Comparison Algorithm

Relevant to your code is the following point of that algorithm (where x is the LHS and y is the RHS).

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

Notice that it actually first attempts to convert the boolean to a number. The false boolean converts to the number 0, so now we have this:

[object Boolean] == 0 

As you can see, it recursively enters the same algorithm because of the ==. So now we're comparing an object to a number and so the following point applies:

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

So here it's now attempting to coerce the object to its primitive value. From 9.1 ToPrimitive, when called on an Object:

Object Return a default value for the Object. The default value of an object is retrieved by calling the [[DefaultValue]] internal method of the object, passing the optional hint PreferredType. The behaviour of the [[DefaultValue]] internal method is defined by this specification for all native ECMAScript objects in 8.12.8.

So you can see that it wants the [[DefaultValue]] of the object. That brings us to 8.12.8 [[DefaultValue]], where it expects a "hint". Because it received no "hint", it behaves as though the hint was "Number".

When the [[DefaultValue]] internal method of O is called with no hint, then it behaves as if the hint were Number,...

And so that brings us to the following behavior:

When the [[DefaultValue]] internal method of O is called with hint Number, the following steps are taken:

  1. Let valueOf be the result of calling the [[Get]] internal method of object O with argument "valueOf".

  2. If IsCallable(valueOf) is true then,

    a. Let val be the result of calling the [[Call]] internal method of valueOf, with O as the this value and an empty argument list.

    b. If val is a primitive value, return val.

And so it calls the .valueOf() method on the object, bringing us to 15.6.4.3 Boolean.prototype.valueOf ( )

  1. Let B be the this value.

  2. If Type(B) is Boolean, then let b be B.

  3. Else if Type(B) is Object and the value of the [[Class]] internal property of B is "Boolean", then let b be the value of the [[PrimitiveValue]] internal property of B.

  4. Else throw a TypeError exception.

  5. Return b.

And so you can see from step 3 that it will return the [[PrimitiveValue]] of the object. That brings us to 15.6.2.1 new Boolean (value)

The [[PrimitiveValue]] internal property of the newly constructed Boolean object is set to ToBoolean(value).

And so you can see that you'll finally get the ToBoolean value of the value you originally passed to the constructor, which was false. Its ToBoolean value is obviously false, so now your comparison is this:

false == 0 

Since the types still don't match, it'll go to point 6 in the original algorithm:

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

And so it now wants to convert the boolean false to a number. This is similar to what was done above. The value false converts to the value 0, so now we have:

0 == 0 

And finally we have a type matched comparison, and so it behaves the same as its strict === counterpart, by comparing values. And clearly, 0 does equal 0, so we get true.


Moral of the story... this is what you get when you ask "why" in JavaScript.

like image 31
2 revsuser2437417 Avatar answered Oct 05 '22 17:10

2 revsuser2437417