I found out the hard way that bitwise operators on bools don't return bools in JavaScript. I thought it must be a bug, but I looked it up in the ECMAScript spec, and sure enough, it says that the bitwise operators return numbers, not bools. It doesn't say a word about the weirdness that results when you're using them on boolean values. Why is it done this way? I've used this technique for years in other languages, so I'm totally baffled why it does something different in JavaScript. Any ideas? Is it just because no one ever uses bitwise operators in this way (except me), or is there a technical reason? I can't imagine it would be hard to check the type and return a boolean.
For reference, the following code:
var found = false;
console.log(found, typeof(found));
found |= true;
console.log(found, typeof(found));
found = true;
console.log(found, typeof(found));
Produces the following output:
false 'boolean'
1 'number'
true 'boolean'
Edit:
By request, I have used this in C, C++, and I'm pretty sure PHP, although I wouldn't swear on it. Yes, I realize that C/C++ are typed, so it would be different internally. I'm just wondering why JavaScript would behave differently.
By request, an example of how I would typically use |=
var foundLowest = false;
for(var k = 0; k < someLength; ++k) {
foundLowest |= someFunctionThatReturnsTF(k);
}
if(foundLowest === true) {
/* do stuff */
}
Logical operators take boolean operands and return a boolean result. The operands for logical operators can be: expressions using relational operators.
5.2. Bitwise OR. Along with integer operands, the bitwise OR can also be used with boolean operands. It returns true if at least one of the operands is true, otherwise, it returns false.
A little bit more into explaining how shift works with a boolean. So true as you said will be 1 and false will be 0.
The bitwise AND operator ( & ) returns a 1 in each bit position for which the corresponding bits of both operands are 1 s.
Having the bitwise operators behave consistently (always convert their operands to numbers) seems like a sufficiently good reason for them to be specified the way they are. A few years ago there was talk on the es-discuss list about adding ||=
and similar shorthand operators, but Eich & Co are very conservative about adding things like that and I seem to recall a comment along the lines that it "didn't pull its syntactic weight." :-)
Note that because JavaScript is happy to coerce any value to a boolean, you can happily use your current style and have it still work, because true
coerces to 1
which coerces to true
, and false
coerces to 0
which coerces to false
. E.g.:
var a = false;
a |= true;
// Even though `a` is now `1`, it works just fine
if (a) {
snippet.log(a + " => if branch"); // Does this one
} else {
snippet.log(a + " => else branch");
}
a &= false;
// Even though `a` is now `0`, it works just fine
if (a) {
snippet.log(a + " => if branch");
} else {
snippet.log(a + " => else branch"); // Does this one
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With