What is the difference?

why in java script is this not correct if(a||b<0){
return undefined
}?
and this is considered the correct solution if(a<0||b<0){
return undefined
}
what is the difference?

The || (or) operator works from left to right and evaluates each expression in turn and if it is true then none of the ones on the right of the || logical operator will get checked. Each part is evaluated without any knowledge of what is after the double pipe ||.

In your example the first part only says if (a ...

All you are asking here is if the variable a exists (is truthy). As a does exist (because it’s already been defined with a value of 2 ) that means that a is ‘truthy’ and passes the test. It is not compared against zero because you had no comparison in that section of the expression. All you asked of it was if it existed. As it does exist it passes the test and none of the other comparisons will get tested because only one needs to be correct to pass the test.

That’s why you need to say if(a < 0 || b < 0). Each part has no relation to what comes after the pipe. e.g. you could be saying instead if (a < 5 || b < 2 || c > 6). Would you then expect a and b to be compared against the number 6?

1 Like

No, I would think that we are looking for the corresponding numbers corresponding to these parameters if (a < 5 || b < 2 || c > 6), but it is not possible to understand the work of javascript using my example, because personally this language is everything to me complicates it because according to its logic and the most difficult thing is to write its code)

Yes it is.

I just told you why it does what it does and the reason for it. It makes perfect and logical sense. I don’t understand why you can’t understand it. :).

You were expecting the parser to always read each and every comparison but it does not do that. It reads from left to right and you asked it if a exists and it said yes so there was no need to look at the other side of the expression.

Perhaps it would have been nice to say something like if((a or b or c) < 0) but that’s not how JS works.

Most other computer languages will use much the same construct as above so this is not solely a js issue. Programming isn’t for everybody and some concepts are much much harder than a simple logical comparison. Programming languages have rules for a reason and you need to learn them and code accordingly.

1 Like

I understood how you said that this is how it works,

I don’t know any programming language in which that would be a construct.

This is just an example of how many students see a recording like this and understand it, but it doesn’t work in the language.

?

It’s a construct, but it doesnt do what you think it does.

a || b < 0
Operator Precedence order says that this is evaluated as
a || (b < 0)
which evaluates the right side of the or into a boolean first
a || true/false
and then evaluates a into a boolean via “truthyness”, for resolving the ||.

This is why you have to do a < 0 || b < 0. The <'s are equal precedence, so they both get evaluated before the ||.

1 Like

Though i’m stretching Precedence there a bit.

For OR and AND, short-circuiting kicks in. So what ACTUALLY happens in that specific case, would be

(a) || (b < 0)
(it would evaluate A’s truthyness first, to see if it needs to figure out what’s on the right side of the OR)

1 Like

You can see that it fails if we compare these 2.

let a = 1
let b = -1

/* not working */
if ((a || b) < 0) {
  console.log("v1... Match found")
} else {
  console.log("v1... No Match found")
}

/* working as expected */
if (a < 0 || b < 0) {
  console.log("V2... Match found")
} else {
  console.log("V2... No Match found")
}

This works…

let a = 0
let b = -1


if ((a || b) != 0) {
  alert("a or b is not 0")
}

Only because of the numbers and the comparison you chose.

let a = 39
let b = 42


if ((a || b) != 42) {
  alert("a or b is not 42")
}

You will see the alert because what gets compared is 39 != 42. In JavaScript, || returns the first truthy value. Your original expression only works because 0 is falsy, so || returns the -1 which then gets compared to 0.

The way || works is why you will often see it used to provide default values for variables, eg:

function someThings(settings){
    settings = settings || {a: 'setting'};
    let a = settings.a || 'nothing';
   alert(a);
}

If the parameter settings is provided when calling that function, it will be used, otherwise it uses the {a: 'setting'} default. Then if settings.a is provided it is used, otherwise 'nothing' is used.

3 Likes

This is also why the Nullish Coalescing Operator exists. Sometimes you WANT to be able to send a 0 through.

0 || 1  //Yields 1
0 ?? 1 //Yields 0

|| will evaluate truthyness, of which there are several “gotcha” values (0, false, null, undefined, document.all, "", NaN, and a couple of others)
?? evaluates Nullness (Nullsy? Nulsy? Nullishness? whatever…) , which is only true for two values: null and undefined.