Reputation: 3203
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 */
}
Upvotes: 12
Views: 5179
Reputation: 1074385
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>
Upvotes: 10