Reputation: 724
I'm confused with how JavaScript turns bitmasks into boolean expressions so you can use them directly in an if-statement. Say, you have two variables, x and y (using Node.JS REPL):
> var x = 0x4;
> var y = 0x5;
Now you AND them and get
> x & y
4
Now you compare to booleans:
> (x & y) == true
false
> (x & y) == false
false
But when you put the bitmask in an if-statement, it works like a charm:
> if (x & y) { z = 3; } else { z = 7; }
3
> if (! (x & y)) { z = 3; } else { z = 7; }
7
So my question is: Although the expression x & y
does not compare to a boolean value, it does in an if-statement. What are the comversion rules or what am I missing here?
Upvotes: 1
Views: 204
Reputation: 3302
Interesting question. The if
part is easier to answer: all values apart from false
, null
, NaN
, 0
, undefined
and the empty string ""
are considered to be truthy - (x & y)
isn't any of those in this case so it's considered to be truthy.
> (x & y) == true
false
Looking up from EcmaScript specs, the "abstract comparison" or ==
works like this when the the two operands (referred to as x
and y
in the document) are of differing types, with the right-hand operand being a boolean:
If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
So while most numeric values are truthy, only the value of true
when casted to a numeric type is equal to true
in the ==
sense. Testing on my own JavaScript console, I get the result 1
from +true
, and likewise, 1 == true
evaluates to true
.
Upvotes: 1
Reputation: 3202
The if
statement in JavaScript is quite easily one of the most debated features on the language, mostly because it does what's called a type coercion. So, it will coerce (x & y), which is a non-zero value, to true which is why you are seeing the result. When you negate it, you also get the result you want. It first coerces ( x & y ) to true, then negates it.
Upvotes: 0