-3

i have the following object:

var quarters = {
                q1:false,
                q2:false,
                q3:false,
                q4:{name: "i'm q4"}
                }

My question is why the following IF is returning true?

if (quarters.q1 == quarters.q2 == quarters.q3 == quarters.q4 == false)

How can i ask if all quarters are false?

The reason I'm not using !quarters.q1 && !quarters.q2 && !quarters.q3 && !quarters.q4 is because sometimes, some of the properties are not defined at all.

TBE
  • 1,002
  • 1
  • 11
  • 32
  • 1
    `toppingOrder` is `undefined` – Dropout Dec 02 '15 at 14:43
  • 7
    `false == false` is `true`, `true == false` is `false`, `false == false` is `true`... you can figure this out with pen and paper. – deceze Dec 02 '15 at 14:44
  • I just fixed the typos – TBE Dec 02 '15 at 14:44
  • 2
    *"The reason I'm not using !quarters.q1 && !quarters.q2 && !quarters.q3 && !quarters.q4 is because sometimes, some of the properties are not defined at all."* – I don't understand why that's a reason to use `==` or how that fixes that issue. – deceze Dec 02 '15 at 14:47
  • @deceze It doesn't. I know i have a mistake, I'm asking how to fix it. I tried to explain what I'm trying to achieve and not How come my code isn't working.... – TBE Dec 02 '15 at 14:50
  • Well, `!quaters.q1 && !quaters.q2 ...` *should* be what you're looking for. That says *if q1 is falsey and q2 is falsey ...*, which is answering the question *are all quarters falsey?* Whether one quarter is undefined or not actually makes no difference here. – deceze Dec 02 '15 at 14:56

2 Answers2

10

why the following IF is returning true?

Assuming toppingOrder is quarters, lets fill it in and see what we have

if (toppingOrder.q1 == toppingOrder.q2 == toppingOrder.q3 == toppingOrder.q4 == false)
// same as
if (false == false == false == {name: "i'm q4"} == false)
// same as
if ((((false == false) == false) == {name: "i'm q4"}) == false)
// same as
if (((true == false) == {name: "i'm q4"}) == false)
// same as
if ((false == {name: "i'm q4"}) == false)
// same as
if (false == false)
// same as
if (true)

How can i ask if all quarters are false?

You either have to loop, use a logical AND && or some Array method like .every

// logical AND `&&`
if (
       false === toppingOrder.q1
    && false === toppingOrder.q2
    && false === toppingOrder.q3
    && false === toppingOrder.q4
    ) // ...

// Array `.every`
if (
    [toppingOrder.q1, toppingOrder.q2, toppingOrder.q3, toppingOrder.q4].every(
            function (e) {return e === false;}
        )
    ) // ...

It is actually much easier to test all true, so consider if you can phrase your if like that instead, e.g. using logical NOT !

if (!toppingOrder.q1 && !toppingOrder.q2 && !toppingOrder.q3 && !toppingOrder.q4) // ...
// or
if (
    [!toppingOrder.q1, !toppingOrder.q2, !toppingOrder.q3, !toppingOrder.q4].every(Boolean)
    ) // ...
Paul S.
  • 64,864
  • 9
  • 122
  • 138
  • Nice explanation, That is what i was looking for: Understanding what I'm doing wrong + understanding how to achieve my goal – TBE Dec 02 '15 at 14:47
  • @TBE to check if they are defined is [another question](http://stackoverflow.com/a/5113396/1326147): for your case you can simply use `e == null`, but notice that `false == null` or `'' == null` both return `false` and `undefined==null` returns `true`. – Armfoot Dec 02 '15 at 15:04
  • @Armfoot checking for _falsy_ is as easy as logical a not, which is why the last edit added a logical not way. Being _falsy_ is more general than being `false`, which is why I didn't answer with it immediately. – Paul S. Dec 02 '15 at 15:09
  • 1
    Paul, I was answering his other comment-question before he edited it out. Btw, you may also want to edit the parenthesis' order in your first block, since the comparison execution is from left to right as [Elentriel mentioned](http://stackoverflow.com/a/34045592/1326147). `2==0==0` and `(2==0)==0` both return `true` but `2==(0==0)` returns `false`. – Armfoot Dec 02 '15 at 15:19
  • 1
    @Armfoot ah yeah, I'm used to ltr invocation in JavaScript but because it has an `=` in there I was treating it like setters instead, thanks will edit – Paul S. Dec 02 '15 at 17:09
2
quarters.q1 == quarters.q2 == quarters.q3 == quarters.q4 == false

true == quarters.q3 == quarters.q4 == false

false == quarters.q4 == false

true == false

What you are essentially doing is this

everything will execute from left to right, unless you set the order (with ( ))

you could go this way about it

function get_bool(quarters){
 for(k in quarters)
 {
  if(quarters[k] != false)
  {
   return true;
  }
 }
 return false;
}
Elentriel
  • 1,237
  • 8
  • 21