why does if("string") evaluate "string" as true but if ("string"==true) does not?

javascript

Solution

It is being cast to Boolean. Any non-empty string evaluates to true.

From the ECMAScript Language Specification:

12.5 The `if` statement

Semantics

The production IfStatement: `if (` Expression `)` Statement `else` Statement is evaluated as follows:

- Let exprRef be the result of evaluating Expression.

- If ToBoolean(GetValue(exprRef)) is true, then

- Return the result of evaluating the first Statement.

- Else,

- Return the result of evaluating the second Statement.

9.2 ToBoolean

The abstract operation ToBoolean converts its argument to a value of type Boolean according to Table 11:

Table 11 - ToBoolean Conversions

Undefined: false Null: false Boolean: The result equals the input argument (no conversion). Number: The result is false if the argument is +0, -0, or NaN; otherwise the result is true. String: The result is false if the argument is the empty String (its length is zero); otherwise the result is true. Object: true

As far as the `==` operator is concerned, it's complicated, but the gist of it is that if you compare a number to a non-number the latter is converted into a number. If you compare a boolean against a non-boolean, the boolean is first converted to a number, and then the previous sentence applies.

See section 11.9.3 for details.

// Call this x == y.
if ("string" == true) 

// Rule 6: If Type(y) is Boolean,
//         return the result of the comparison x == ToNumber(y).
if ("string" == Number(true))

// Rule 5: If Type(x) is String and Type(y) is Number,
//         return the result of the comparison ToNumber(x) == y.  
if (Number("string") == Number(true))

// The above is equivalent to:
if (NaN == 1)

// And NaN compared to *anything* is false, so the end result is:
if (false)

Problem

Given the following code: ``` if ("string") { console.log('true!'); } //logs "true" to the console if ("string"==true) { console.log('true!'); } //doesn't log anything ``` Why does this happen? I thought `"string"` was being cast to a number, as is the boolean. So `true` becomes `1`, and `"string"` becomes `NaN`. The second if statement makes sense, but I don't see why the first statement causes the inner loop to be evaluated. What's going on here?

Original source