What this shows is that when a Boolean object is used in an
if statement, it always evaluates to
true, but when it’s used in a type coercing operator (such as
==), it converts to the value it represents. Why?
The reason is actually pretty straightforward, even though it’s not obvious when looking at it.
if statements convert the result of their expression to a boolean primitive, whereas
== converts the right side expression into the type of the left side and checks for equivalency. So
if statements don’t do type conversion at all until the expression is evaluated, and then it implicitly converts the result of that expression into a boolean primitive.
true. And guess what? Instances of
Boolean are objects:
Boolean instances are objects, they will always be
true when converted to a boolean primitive, which is exactly what the
if statement is doing.
So then, why does
new Boolean(false) == false result in
true? Well it’s because the rules are different for
==. Let’s say you’re doing
false == new Boolean(false). This will result in
true because the left side of the expression is a primitive, so the interpreter will convert the Boolean instance, not to a boolean, but to a primitive. When converting an object to a value, the interpreter will:
Return a default value for the Object. The default value of an object is retrieved by calling the internal [[DefaultValue]] method of the object, passing the optional hint PreferredType. The behaviour of the [[DefaultValue]] method is defined by this specification for all native ECMAScript objects (22.214.171.124).
And, you guessed it, the default value of a Boolean instance is just the boolean primitive that it represents. So, after conversion, we’re testing
false which is of course true.
The other direction also works. If we’re doing
(new Boolean(false)) == false , then the interpreter will convert
false to an
Object. The spec specifies that to convert a boolean primitive to an object, it should:
Create a new Boolean object whose [[value]] property is set to the value of the boolean.
So then we have two equivalent Boolean instances being compared, which again results in
Pretty crazy, but it kind of makes sense when you think about it. Maybe.