1

What is the difference between these two conditional statements in Javascript?

function comparisonTest() {
  var value = "A value";
  var compare1 = 5;
  var compare2 = "String";
  var compare3 = false;

  if (value == compare1 || value == compare2 || value == compare3) console.write("True");
  else console.write("False");
}

This works as it should - it returns false because the values don't match. However, when I change the conditional to the following...

function comparisonTest() {
  var value = "A value";
  var compare1 = 5;
  var compare2 = "String";
  var compare3 = false;

  if (value == compare1 || compare2 || compare3) console.write("True");
  else console.write("False");
}

it always returns True. I thought that maybe there would be a shorter way of writing that condition for multiple comparisons (although a loop would function just fine), but this is clearly not a way to approach this.

What is going on behind-the-scenes or, rather, how is it being interpreted so that in the second case it always returns true? None of the values I declared are 1 or true, so that's definitely not the problem.

Chris Cirefice
  • 5,475
  • 7
  • 45
  • 75

3 Answers3

2

That's because this:

if (value == compare1 || compare2 || compare3) 

is the same as this:

if ((value == compare1) || compare2 || compare3)

And, you will see that compare2is a truthy value which satisfies the || operator. See this MDN article on operator precedence for why the == gets evaluated first which makes your first code block work, but makes your second one evaluate like I've shown.


If you want to compare all of them to value, you have to write it out the longhand way like you did in your first code block where you compare each one separately to value.


You may also want to look into using === more often so then you don't have to worry about possible type conversions making things equal that you never intended to be equal. I have a guideline in my own coding to always used === and !== unless there's an explicit reason to want a type conversion. I believe this saves some accidental bugs. See here for more info.

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Thank you for the evaluation of the second conditional to how the compiler interprets it - I was wondering how it determined what to evaluate. Also, I appreciate you pointing out the use of `===`, however the type conversion was something that I knew was not an issue in this case. As well, I have already read that SO question, but thank you for linking it nonetheless! – Chris Cirefice Nov 04 '13 at 00:14
  • @ChrisCirefice - you may find this article on operator precedence in javascript useful: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence – jfriend00 Nov 04 '13 at 00:19
  • The choice of equality operator is irrelevant here. – RobG Nov 04 '13 at 00:21
  • @RobG - yes I know that - just a general "good coding" recommendation when they are mixing types. – jfriend00 Nov 04 '13 at 00:57
  • Hmmm, "good coding". I've never seen a good argument to **always** use one over the other—if `'5' !== 5` is required, the programmer had better be certain. But that discussion has been held elsewhere. ;-) – RobG Nov 04 '13 at 03:34
  • @RobG - My guideline for my own coding is that unless I explicitly want a type conversion, I should ALWAYS use `===` or `!==`. I didn't say everyone should always do that or that's the only way to do it. I said that it's a guideline I use and I believe it prevents bugs, thus I recommend it to others. – jfriend00 Nov 04 '13 at 03:45
  • I have to agree with both of you. 1. The different types were simply to demonstrate the question - in reality the entire block is full of strings. However, I do always use `===` when I'm checking values I know to be of a certain type (as in my 'real' case, where I'm looking for `if (value === stringX)`. Thank you for the warning though :) – Chris Cirefice Nov 04 '13 at 04:42
2

Here is another option:

function comparisonTest() {
  var value = "A value";

  var answers = [5, "String", false];

  /* IE may requires shim found here:
     https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
  */
  if (answers.indexOf(value) === -1) {
    // False
  } else {
    // True
  }
}
Jeremy J Starcher
  • 23,369
  • 6
  • 54
  • 74
  • This is brilliant! And actually, it's just what I needed. I have a list of about 100 comparison strings that I previously put into an array and looped through (sloppy); this is *much* more elegant, thank you :) – Chris Cirefice Nov 04 '13 at 04:39
  • The usual ES5 caveat should be included, but +1 anyway. :-) – RobG Nov 04 '13 at 06:34
  • @RobG -- I assume you are referring to the shim being needed? Yea, I meant to include that. – Jeremy J Starcher Nov 04 '13 at 14:07
  • This is all server-side Google code that doesn't actually run in any browser. It's just used to script Google's services (Calendar, Spreadsheet, etc.) and their back-end is up-to-date :) – Chris Cirefice Nov 04 '13 at 16:04
1

Unfortunately I do not believe there is a short way to write conditionals in JavaScript.

The reason the second example returns true is because when you evaluate compare2 this is a truthy value in JavaScript.

I recommend this post about truthy and falsey values in JavaScript

As an aside you may want to look into the difference between == and === in JavaScript

Mark Meyer
  • 3,643
  • 3
  • 23
  • 34
  • I'll accept this answer soon - thank you for the reference; I didn't know that there were `truthy` and `falsey` values in Javascript... this is interesting, and I'll keep it in mind when I'm working with Javascript! I take this over the answer from @jfriend00 because you gave me a reference that actually explains what the values are and what they mean. – Chris Cirefice Nov 04 '13 at 00:12