Reputation: 43
I'm new in JavaScript, and I just discovered strange behavior that I can't understand:
var magicVar = Math.sin;
magicVar == true; // it returns false
magicVar === true; // it returns false
if (magicVar) console.log("???"); // it prints "???"
What is happening?
Thank you.
Upvotes: 3
Views: 6153
Reputation: 4971
var magicVar = Math.sin;
From here on magicVar
is a reference to the Math.sin
function, which is actually an Object
(see Function on MDN)
The Function constructor creates a new Function object. In JavaScript every function is actually a Function object.
magicVar == true; // it returns false
This is false
: from the Equality comparison and sameness on MDN if you compare an operand of type Object
with an operand of type Boolean
using the ==
operator you always get false
(look at the Loose equality using == table).
[EDIT] As Bergi pointed out in the comments you could actually in some cases have objects that loosely compared to a boolean value return true.
What is actually happening behind the scenes is that the comparison algorithm described in ES6 §7.2.12 is applied.
7.2.12 Abstract Equality Comparison
The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:
- ReturnIfAbrupt(x).
- ReturnIfAbrupt(y).
- If Type(x) is the same as Type(y), then Return the result of performing strict Equality Comparison x === y.
- If x is null and y is undefined, return true.
- If x is undefined and y is null, return true.
- If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).
- If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y.
- If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
- If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
- If Type(x) is either String, Number, or Symbol and Type(y) is Object, then return the result of the comparison x == ToPrimitive(y).
- If Type(x) is Object and Type(y) is either String, Number, or Symbol, then return the result of the comparison ToPrimitive(x) == y.
- Return false.
In your case what happens is:
magicVar == true
magicVar == Number(true) // Step 9. x == ToNumber(y).
magicVar == 1
toPrimitive(magicVar) == 1 // Step 11. ToPrimitive(x) == y.
magicVar.toString() == 1
"function sin() { [native code] }" == 1
Number("function sin() { [native code] }") == 1 // Step 7. ToNumber(x) == y.
NaN === 1 // Step 3. x === y.
false
But comparing for example to an object like:
{
valueOf: function(){
return 1;
}
}
you would get:
true == {valueOf(){return 1;}} // it returns true
magicVar === true; // it returns false
This is trivially false
, the types of the operands are different and the ===
operator checks for the operands to have same types and values.
if (magicVar) console.log("???"); // it prints "???"
As all the others answers have said magicVar
here is in a Boolean
context and gets coerced to true
Upvotes: 4
Reputation: 10849
The concept to grasp here is the difference between truthy and falsy values compared to true and false booleans. See here for truthy and here for falsy
Long story short, an if
condition passes if the expression is truthy, and magicVar
is a function
(truthy).
Upvotes: 1
Reputation: 1159
magicVar
is true as a value. It is true in the sense that it's not empty, it's not null or undefined. So, any non-null value would be a true value. But is this value equal to true ? No. It is true as a boolean not true as a value.
To summarize:
magicVar == true || magicVar === true; // returns false
Boolean(magicVar); // returns true
Upvotes: 2
Reputation: 19
Comparison function Math.sin
with boolean
constant return false
, because this variables have different types.
But when you put not-bool variable to if
condition: for example if (Math.sin)...
or if (window)...
this return true if variable not equal null.
Upvotes: 0
Reputation: 169
magicVar is not equal to true. It is equal to the Math.sin function.
So, in the if statement, it is evaluated to a truthy value (it is defined and does not evaluate to a falsy value).
http://www.sitepoint.com/javascript-truthy-falsy/
Upvotes: 0