I've encountered something which seems inconsistent on the part of the interpreter, though I know it probably makes sense and I just don't understand it. It has to do with evaluating the equality of a truthy/falsy values and Booleans.
Example 1:
if (document.getElementById('header')) {
//run code here
}
If the element with an id of 'header' is found in the document, the condition is true because the presence of an object is considered truthy.
Example 2:
if (document.getElementById('header) == true) {
// run code here
}
Presuppose the referenced element is found within the document. It was explained to me that this condition will evaluate to false because a truthy value does not equal a Boolean value of true.
This doesn't seem to make sense. The presence of the object is considered truthy due to type coercion, so therefore it should equal true even though the data types are different.
Consider the following:
(false == 0) // evaluates to true
(false === 0) // evaluates to false
This is a case where false equals 0 is true when you use the equals to operator. Because 0 is considered a falsy value, it is equal to the Boolean value of false. The values are the same and the data types are different.
To me, (document.getElementById('header') == true) and (false == 0) are the same thing. And yet, they both evaluate to something different.
Can someone please explain to me why this is the case? I've been reading different descriptions of this, but no one seems to explain it in-depth.
document.getElementById('header')
returns a DOM object ornull
. So, in your second comparison (assuming it is resolving to an object), you're comparing:A DOM object is not
==
totrue
.To see why, you have to go to the ECMAScript rules for automatic type conversion which you can see in the ECMAScript 5 specification here: http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3.
The operative rules when comparing an
object == boolean
are all the way down to rules 9 and 10.Rule 9 is the first rule where
Type(x)
isObject
and the two types are not the same, so it's the first one to check.Since
Type(y)
isBoolean
, it does not pass rule 9.Thus, when it hasn't passed any rules 1-9, it evaluates to
false
.When you do this comparison:
you're looking at rule #6 in the type conversion rules which will do:
which will resolve to:
which will be
true
.For this one:
Whenever you use
===
, if the two types are different, then the result is immediatelyfalse
so this evaluates tofalse
.===
requires type AND value to be the same so if the type is not the same, then it doesn't even attempt to compare the value. No type conversion is ever done with===
which is one of the useful reasons to use it.You should understand that the
truthy
andfalsey
rules apply to only a single check like this with no==
or===
in the comparison:They do not apply when you are comparing
x == y
. For that, you have to refer to the type conversion rules in section 11.9.3 of the specification (linked above).When the if() statement is executing, it's checking if there is a truthy value inside the parenthesis. The == operator is checking whether the two values are equal in nature. In JavaScript, true and false are == to 1 and 0, respectively; hence why you can type (4 + true) and get 5, or false*6 and get 0!
When you type
something == true
, you're really checking ifsomething == 1
. If something isn't a boolean value it's not going to be the same as 1.Perhaps an explanation of your postulate "The presence of the object is considered truthy due to type coercion, so therefore it should equal true."
The conclusion does not follow, so therefore the postulate is invalid. In general, you should use === if you need to check if two things are truly the same thing.
Hopefully this clears things up!
You're right, it doesn't make sense because whoever explained that to you is wrong.
The presence of a DOM element will evaluate to true and if it doesn't exist, it will evaluate to false (with a double-equals vs. triple). If in the event they are using triple equals, you can simply try:
!!document.getElementById('someNodeId')
and it will return a boolean value.You can always try this in the console if you want to be sure.
Edit: I didn't read the example clearly or the example was updated. Yeah, you're using double equal. The element is truthy, but it's not "true".