NickW
NickW

Reputation: 1333

logical OR and precedence

I've just been watching a tutorial which talked about the following if statement:

var a = 0;
if(a || a === 0){...};

It states that operator precedence means that a === 0 is evaluated first, as it has a higher precedence than ||.

I've no real issue with that, but the tutorial goes on to say that 'a' is then evaluated - but surely it's short-circuited?

I know it should be pretty simple, but I'm new to JS. Is this a mistake or am I misunderstanding what's being said?

Upvotes: 1

Views: 61

Answers (2)

Nick is tired
Nick is tired

Reputation: 7055

No, the equivalence doesn't happen first:

var a = 0;
if(a || a === 0){...}

The a in this case is falsey and so the || continues onto the next statement, equivalent to:

if(a === 0){...}

At this point, the equivalence takes place and is clearly true, no short circuiting takes place because the expression is evaluated left to right.


The reason for this is that either side of the OR is a different expression and the expressions are evaluated from left to right.

expr1 || expr2

Once expr1 has been evaluated, if it is truthy only then does short-circuiting take place and the expression as a whole be truthy. If this isn't the case expr2 will be evaluated and if that is truthy then the expression as a whole will be truthy, otherwise it will be falsey.

Upvotes: 1

Mark
Mark

Reputation: 92440

You can test this easily enough with a getter. If a is true, the getter is called once, meaning that obj.a === 0 is never evaluted due to short-circuiting:

let obj =  {
    get a() {
        console.log("getting a")
        return true
    }
}
if(obj.a || obj.a === 0){
    console.log("true")
};

If a is falsey as is the case when a id 0 , both side are evaluated:

let obj =  {
    get a() {
        console.log("getting a")
        return 0
    }
}
if(obj.a || obj.a === 0){
    console.log("true")
};

Upvotes: 4

Related Questions