Reputation: 10425
In JavaScript
(f1() || f2())
won't execute f2
if f1
returns true
which is usually a good thing except for when it isn't. Is there a version of ||
that doesn't short circuit?
Something like
var or = function(f, g){var a = f(); var b = g(); return a||b;}
Upvotes: 29
Views: 4578
Reputation: 81
Non-shortcircuiting and: [f1(), f2()].every(i => i)
Non-shortcircuiting or: [f1(), f2()].some(i => i)
To test non-shortcircuiting and in Chrome console, exectute this:
f1 = () => { console.log('evaluating f1'); return false; }
f2 = () => { console.log('evaluating f2'); return false; }
[f1(), f2()].every(i => i)
Result:
evaluating f1
evaluating f2
false
To test non-shortcircuiting or in Chrome console, exectute this:
f1 = () => { console.log('evaluating f1'); return true; }
f2 = () => { console.log('evaluating f2'); return true; }
[f1(), f2()].some(i => i)
Result:
evaluating f1
evaluating f2
true
The square bracket syntax is called array literal. The array is filled with the return values of the functions f1
and f2
, which are both evaluated. Then the logic operation is done with each array element as an operand. The logic operations themselves are shortcircuiting, but that does not matter because the operands have already been evaluated. So the construct as a whole is non-shortcircuiting.
Documentation:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#array_literals
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
Upvotes: 1
Reputation: 3708
&
and |
are bitwise, but if the inputs are booleans, you can often ignore the fact that the result is 0 or 1:
if (f1() | f2())
If you need a boolean result, use "double not" to convert 0 and 1 to false
and true
respectively:
const orResult = !!(f1() | f2());
If the inputs aren't booleans and you want to be compatible with JavaScript way of treating 0
, -0
, NaN
, undefined
, null
as false
:
const andResult = !!(!!f1() & !!f2());
const orResult = !!(!!f1() | !!f2());
These can be shortened using De Morgan's laws to:
const andResult = !(!f1() | !f2());
const orResult = !(!f1() & !f2());
although the "double not" reads better to me.
Upvotes: 0
Reputation: 5400
Nope, JavaScript is not like Java and the only logical operators are the short-circuited
https://developer.mozilla.org/en/JavaScript/Reference/Operators/Logical_Operators
Maybe this could help you:
http://cdmckay.org/blog/2010/09/09/eager-boolean-operators-in-javascript/
| a | b | a && b | a * b | a || b | a + b |
|-------|-------|--------|-----------|--------|-----------|
| false | false | false | 0 | false | 0 |
| false | true | false | 0 | true | 1 |
| true | false | false | 0 | true | 1 |
| true | true | true | 1 | true | 2 |
| a | b | a && b | !!(a * b) | a || b | !!(a + b) |
|-------|-------|--------|-----------|--------|-----------|
| false | false | false | false | false | false |
| false | true | false | false | true | true |
| true | false | false | false | true | true |
| true | true | true | true | true | true |
Basically (a && b)
is short-circuiting while !!(a + b)
is not and they produce the same value.
Upvotes: 14
Reputation: 17825
JavaScript DOES have single pipe (|
, bitwise OR) and single ampersand operators (&
, bitwise AND) that are non-short circuiting, but again they are bitwise, not logical.
http://www.eecs.umich.edu/~bartlett/jsops.html
Upvotes: 2
Reputation: 2722
If you need f2() to run regardless of whether or not f1() is true or false, you should simply be calling it, returning a boolean variable, and using that in your conditional. That is, use: if (f1() || f2IsTrue)
Otherwise, use single bar or single ampersand as suggested by GregC.
Upvotes: 1
Reputation: 8605
You could use bit-wise OR as long as your functions return boolean values (or would that really matter?):
if (f1() | f2()) {
//...
}
I played with this here: http://jsfiddle.net/sadkinson/E9eWD/1/
Upvotes: 4