Exactly why does the condition here evaluate to true?
var condition = new Boolean(false); if (condition == !condition) alert("The more you know...");
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.
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.
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.
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
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:
Let valueOf be the result of calling the [[Get]] internal method of object O with argument "valueOf".
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 ( )
Let B be the this value.
If Type(B) is Boolean, then let b be B.
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.
Else throw a TypeError exception.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With