###Problem:
An exercise requires you to compare the user’s input string is either “apple”, “banana” or “guava”. Armed with your new-found knowledge of if
blocks and conditional operators - &&
, ||
and !
- you decide to write the following concise code:
if(input === "banana" || "guava" || "apple")
console.log("PASSED!");
else
console.log("FAILED!");
Run online
Did you instead use commas like this: if(input === "banana", "guava", "apple")
? Then read this post also.
You take it for a spin and it prints "PASSED!"
for inputs "banana"
, "guava"
and "apple"
. But then you enter words like "fruit"
or "cat"
or "unicorn"
and it still prints "PASSED!"
. After several more test runs, you come to the horrific conclusion that your program always prints "PASSED"
.
So, in this FAQ, we are going to have a look at why this is happening and how we can fix it.
###Why does it happen?
Remember the operator precedence table, the ===
operator has higher precedence than ||
, so after applying parenthesis, the actual manner in which the interpreter reads our code is:
if ( (input === "banana") || ("guava") || ("apple") )
which are three separate expressions joined by the ||
operator:
input === "banana"
"guava"
"apple"
Notice the last two expressions, which are not really expressions at all but simple string literals!
However, due to the way we wrote our if
condition, the last two expressions are forcibly interpreted by the interpreter as a boolean value (true
or false
). Now, remember that any string that is empty (""
) is interpreted to be false
and all non-empty strings are true
. So, our "guava"
string is read to be true
, and so is "apple"
, as they are not empty strings.
Now, in expressions 1, 2 and 3, expressions 2 and 3 are always true
, since these are constant string literals and do not depend on user input. Expressions 1, 2 and 3 are joined by the ||
operator, so even if one expression is true the entire condition becomes true
. Hence, our if
block evaluates to true
and so "PASSED!"
is printed.
###How to fix this problem?
There are three ways to do this:
1. Write your condition properly
Instead of:
if(input === "banana" || "guava" || "apple")
write:
if(input === "banana" || input === "guava" || input === "apple")
2. Use switch-case with a combination of fall-through
switch(input){
case "banana:"
case "guava":
case "apple":
console.log("PASSED!"); break;
}
3. Use arrays
var valid = ["banana", "guava", "apple"];
if(valid.indexOf(input) > -1) console.log("PASSED!")
Note: You might not have been taught arrays or switch-case up until this point in the course. Do not worry, these are only indicative and alternative solutions and you can always use the first solution.
Hope it helps!