3

I would like to know in this example why my condition is always true ? Thanks

function bla() {
  var qix = 'z'
  if (qix === 'a' || 'b' || 'c') {
     console.log('condition ok!! whats wrong???')
  }
}
maxd
  • 73
  • 2
  • 7
  • There are two `"c"` in your condition. – Takit Isy Apr 09 '18 at 14:18
  • 4
    You've misunderstood how the `||` operator works. – Pointy Apr 09 '18 at 14:18
  • Possible duplicate of [How to use OR condition in a JavaScript IF statement?](https://stackoverflow.com/questions/2363840/how-to-use-or-condition-in-a-javascript-if-statement) – Ele Apr 09 '18 at 14:23
  • Possible duplicate of [Javascript: The prettiest way to compare one value against multiple values](https://stackoverflow.com/questions/9121395/javascript-the-prettiest-way-to-compare-one-value-against-multiple-values). Voted to close as that, but I actually meant [Javascript If statement used to check file extensions not working](https://stackoverflow.com/q/11836081/4642212). Oh well. – Sebastian Simon Apr 09 '18 at 14:30
  • I think there is no need of a strict comparison here. (https://stackoverflow.com/questions/523643/difference-between-and-in-javascript) – Takit Isy Apr 09 '18 at 14:30
  • 2
    @TakitIsy It’s considered good practice to always use `===`, and `==` only when applicable. – Sebastian Simon Apr 09 '18 at 14:33
  • @Xufox, and so, when is `==` applicable ? – Takit Isy Apr 09 '18 at 14:35

7 Answers7

17

The problem with your code is that the if expression always evaluates to true.

qix === 'a' || 'b' || 'c'

will actually become this:

false || 'b' || 'c'

as qix is set to z. Due to loose typing, JavaScript returns true for the second expression because 'b' is a truthy value. To correct that, you need to change the expression as follows:

qix === 'a' || qix === 'b' || qix === 'c'

so that it correctly means what you're expecting.

31piy
  • 23,323
  • 6
  • 47
  • 67
4

Description of expr1 || expr2 from MDN:

Returns expr1 if it can be converted to true; otherwise, returns expr2. Thus, when used with Boolean values, || returns true if either operand is true.

o1 = true  || true       // t || t returns true
o2 = false || true       // f || t returns true
o3 = true  || false      // t || f returns true
o4 = false || (3 == 4)   // f || f returns false
o5 = 'Cat' || 'Dog'      // t || t returns "Cat"
o6 = false || 'Cat'      // f || t returns "Cat"
o7 = 'Cat' || false      // t || f returns "Cat"
o8 = ''    || false      // f || f returns false
o9 = false || ''         // f || f returns ""

So this expression from your code, assuming qix is not 'a':

qix === 'a' || 'b' || 'c'

The first term qux === 'a' is false, which of course evaluates to false. This causes it to go to the next term which is 'b'. Non-empty strings evaluate to true, so it stops there and just becomes 'b'. Now your if statement can be thought of as just:

if ('b')

Again, 'b' evaluates to true. So your conditional is effectively doing nothing.

sripberger
  • 1,682
  • 1
  • 10
  • 21
2

I think you are missing two concepts.

First how the || operator works and second coercion of javascript values.

In your code:

  if ('z' === 'a' || 'b' || 'c') { ----}

Will always evaluate to true. The reason for this is that the || operator will give back the first value which coerces to true without actually coercing the value. The associativity (order which the operators are executed) is left-to-right. This means that the following happens:

First the following will be evaluated because it has higher precedence:

'z' === 'a' // false

then we have the following expression which will be evaluated left to right:

false || 'b' || 'c'

let foo = false || 'b'

console.log(foo)

Then we have the following expression:

let foo = 'b' || 'c'

console.log(foo)

So the whole expression evulates to the string 'b'

After the expression inside the if statement is evaluated to the value 'b' this in turn then gets coerced into a boolean. Every string gets converted to true and that's why the value is always true.

Willem van der Veen
  • 33,665
  • 16
  • 190
  • 155
1

As we know || (OR Logical Operators) returns true if either operand is true. In your if condition qix === 'a' || 'b' || 'c' in their second and third operand is string and Strings are considered false if and only if they are empty otherwise true. For this reason, your condition is always true.

Need to check qix like qix ==='b'

 var qix = 'z'
  if (qix === 'a' || qix === 'b' || qix ==='c') {
     console.log('condition ok!! whats wrong???')
  }
  else{
      console.log('else')
  }
Mohammad Ali Rony
  • 4,695
  • 3
  • 19
  • 33
1

This is because you 'if condition' is take 3 possible option

First say qix === 'a', this is false but you asking about 'b','c' and this option are values true because you are not compare var qix with 'b' or 'c', you only asking to IF condition, that if 'b' or 'c' are value

the operator || it is used so

if(First Condition || Second Condition || third condition){
 if at least one of these options is true, then enter here
}

In ECMAScript 2016 incorporates an includes() method for arrays that specifically solves the answer

if (['b', 'c', 'a'].includes(qix)) {
    this is false
}

if (['z', 'c', 'a'].includes(qix)) {
    this is true
}

Or you can write so

function bla() {
  var qix = 'z'
  if (qix === 'a' || qix === 'b' || qix === 'c') {
     console.log('condition ok!! whats wrong???')
  }
}
0

JavaScript returns true for the second or expression because 'b' is always true.

You need to check each value against qix like so:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators

  var qix = 'z'
  if (qix === 'a' || qix === 'b' ||  qix === 'c') {
     console.log('condition ok!! whats wrong???')
  }
Scath
  • 3,777
  • 10
  • 29
  • 40
0

You could use Regex: qix.match(/^(a|b|c)$/)
Should return if qix is equals to a or b or c

var qix = 'z';
if (qix.match(/^(a|b|c)$/)) {
   console.log('condition ok!! whats wrong???');
} else {
   console.log('else');
}
André
  • 4,417
  • 4
  • 29
  • 56