5

I always thought that an if statement essentially compared it's argument similar to == true. However the following experiment in Firebug confirmed my worst fears—after writing Javascript for 15 years I still have no clue WTF is going on:

>>> " " == true
false
>>> if(" ") console.log("wtf")
wtf

My worldview is in shambles here. I could run some experiments to learn more, but even then I would be losing sleep for fear of browser quirks. Is this in a spec somewhere? Is it consistent cross-browser? Will I ever master javascript?

gtd
  • 16,956
  • 6
  • 49
  • 65

5 Answers5

7

"If the two operands are not of the same type, JavaScript converts the operands then applies strict comparison. If either operand is a number or a boolean, the operands are converted to numbers; if either operand is a string, the other one is converted to a string."

https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Comparison_Operators

So the first one does:

Number(" ")==Number(true)

While the second one is evaluated like this:

if(Boolean(" ")==true) console.log("wtf")
kloffy
  • 2,928
  • 2
  • 25
  • 34
  • This is the most sensible explanation. The if statement casts to Boolean. Bonus points if anyone can find a spec for this behavior. – gtd Oct 23 '09 at 21:46
  • 1
    Well, the Mozilla docs have the following to say regarding the conversion taking place in the if statement: "Any value that is not undefined, null, 0, NaN, or the empty string (""), and any object, including a Boolean object whose value is false, evaluates to true when passed to a conditional statement." – kloffy Oct 23 '09 at 21:58
  • And this concerning the conversion using Boolean(value): "If value is omitted or is 0, -0, null, false, NaN, undefined, or the empty string (""), the object has an initial value of false." – kloffy Oct 23 '09 at 21:58
  • 2
    A JS Ninja friend of mine just IMed me this spec: http://bclary.com/2004/11/07/#a-11.9.3 – Bart Oct 23 '09 at 22:00
3

I am guessing that it is the first part that is a problem, not the second.

It probably does some weird casting (most likely, true is cast to a string instead of " " being cast to a boolean value.

What does FireBug return for Boolean(" ") ?

DVK
  • 126,886
  • 32
  • 213
  • 327
  • Well, holy wars have been perpetuated merely by the definition of truthiness in programming languages, but in javascript I just assumed that since == does casting and === is an exact match, == true would be the natural definition of truthiness. – gtd Oct 23 '09 at 21:32
  • Boolean(" ") => true Boolean("") => false – gtd Oct 23 '09 at 21:37
  • So, the answer is *probably* that the "==" operator does backwards casting (true => string "true") and then comparison fails. Kille me if I can find ANY reference that specifies just what the casting rules for "==" are though – DVK Oct 23 '09 at 21:42
  • Check out the next two answers :) – gtd Oct 23 '09 at 21:45
3

JavaScript can be quirky with things like this. Note that JavaScript has == but also ===. I would have thought that

" " == true

would be true, but

" " === true

would be false. The === operator doesn't do conversions; it checks if the value and the type on both sides of the operator are the same. The == does convert 'truthy' values to true and 'falsy' values to false.

This might be the answer - from JavaScript Comparison Operators (Mozilla documentation):

Equal (==)

If the two operands are not of the same type, JavaScript converts the operands then applies strict comparison. If either operand is a number or a boolean, the operands are converted to numbers; if either operand is a string, the other one is converted to a string

Highly recommended: Douglas Crockford on JavaScript.

Community
  • 1
  • 1
Jesper
  • 202,709
  • 46
  • 318
  • 350
  • Good link, I had Javascript: The Good Parts, but I don't know where it ran off to. – gtd Oct 23 '09 at 21:34
2

Answer: aTruthyValue and true are not the same.

The semantic of the if statement is easy:

if(aTruthyValue) {
  doThis
} else {
  doThat
}

Now it's just the definition of what a truthy value is. A truthy value is, unfortunately, not something that is simply "== true" or "=== true".

ECMA-262 1.5 Setion 9.2 explains what values are truthy and which are not.

0

I recommend using === whenever possible, if only to avoid having existential crises.

Adam Bard
  • 1,693
  • 1
  • 11
  • 17
  • This is pure silly. String.prototype.f = function () { return this }; "foo".f() === "foo" // what is the result? Identity is identity. It is a special case, not the normal case. –  Oct 23 '09 at 21:49