开发者

Does JavaScript have non-shortcircuiting boolean operators?

开发者 https://www.devze.com 2023-02-24 04:28 出处:网络
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?

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;}


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.


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/


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


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.


Non-shortcircuiting and: [f1(), f2()].every(i => i)

Non-shortcircuiting or: [f1(), f2()].some(i => i)

Documentation:

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


& 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消