SaganRitual
SaganRitual

Reputation: 3203

JavaScript: why does bitwise OR of booleans return a number instead of a boolean?

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

Answers (1)

T.J. Crowder
T.J. Crowder

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

Related Questions