2

I'm running a UI component on every page and on one of the pages, there's an extra functionality linked to it. The UI component has a boolean called MyValue and the extra functionality has an object called ExtraObject and one of its properties is a boolean called ExtraBool.

I want to test if MyValue is true AND if ExtraObject.ExtraBool is false, BUT ONLY if ExtraObject exists. That way, if I'm on the pages that don't have ExtraObject, there's no error.

I tried this:

if (MyValue === true && 
    (typeof ExtraObject === undefined || ExtraObject.ExtraBool === false)) {...}

How should I rewrite this?

At the moment, I keep getting "ExtraObject is not defined error".

Thanks.

3
  • You don't really need to compare the boolean values to true and false; just refer to the variable or its logical completment (!ExtraObject.ExtraBool) Commented Jun 12, 2012 at 20:57
  • @Pointy, although I doubt someone having problems with low-level boolean logic would run into this, it's possible that MyValue needs to be true but could have alternative values such as 1, or 'false', where it would be necessary to perform a strict equality comparison. Commented Jun 12, 2012 at 20:58
  • looks like OP is missing a close paren on the if statement... Commented Jun 12, 2012 at 20:59

4 Answers 4

2

That should be:

typeof ExtraObject === "undefined"

typeof returns the type of the expression as a string, so you need to compare the name "undefined" to the result.

In my opinion, your condition is a bit too explicit. I'd go with something shorter:

if (MyValue && !(ExtraObject && ExtraObject.ExtraBool)) {...}

If you're communicating with your own GUI code, you can assume that the types are as expected. Type checking in JavaScript is rather cumbersome, so if you know what you're dealing with you can be less explicit. (This doesn't apply to user input though. Never trust user input.)

Sign up to request clarification or add additional context in comments.

4 Comments

Fixed again, so the condition evaluates to true if MyValue is true and ExtraObject is undefined. Had to check your comment on the other answers to verify.
"if MyValue is true AND if ExtraObject.ExtraBool is false, BUT ONLY if ExtraObject exists"
Anyway, the solution you provided to test undefined in quotes is good. I prefer long code that's easy to read and then in the end I put it through google closure compiler and get the output optimized.
Another way would be to just test ExtraObject === undefined, but then you might want to locally redefine undefined to make sure it's actually undefined.
1

The logic is not quite correct:

if (MyValue && ExtraObject && !ExtraObject.ExtraBool) { ... }

I'm guessing that null would be a value ExtraObject shouldn't have either; that is, I presume that you r condition is really better stated that it should be a reference to an object.

Thus, the condition as I wrote it will be true when MyValue is "truthy", ExtraObject is a reference to a real object, and the property ExtraBool on that object is "falsy".

Sometimes it's necessary to make explicit comparisons to boolean constants, but in my opinion it's a code smell. (Of course, it can also be dangerous to just check truthiness/falsiness ...)

edit If your requirement is that the expression be true when MyValue is true and either ExtraObject is not a reference to an object or it's ExtraBool property is true, then I'd write that:

if (MyValue && (!ExtraObject || !ExtraObject.ExtraBool)) { ... }

Which is "better" is a matter of personal preference and experience.

5 Comments

no, if ExtraObject is undefined and MyValue === true then the condition is met
Well @frenchie OK but your question is worded incorrectly then.
where? "if MyValue is true AND if ExtraObject.ExtraBool is false, BUT ONLY if ExtraObject exists"
There's no "or" in your wording; I agree however that it's not incorrect, but it is ambiguous, because it's not clear what the "BUT ONLY" part relates to.
the "BUT ONLY" part relates to ExtraObject: we're testing for ExtraObject.ExtraBool === false ONLY if ExtraObject exists.
1

Truth table time!

A is MyValue*
B is window.ExtraObject**
C is ExtraObject.ExtraBool

A B C | O
------+--
0 0 0 | 0
0 0 1 | 0
0 1 0 | n/a***
0 1 1 | 0
1 0 0 | 1
1 0 1 | n/a***
1 1 0 | 1
1 1 1 | 0

What we find with these values is that the simplest equation to produce O is:

A && !C

So your code should be:

if (MyValue && !ExtraObject.ExtraBool) {}

But of course, you mentioned not wanting to run into issues if ExtraObject wasn't defined:

var extraBool = window.ExtraObject ? ExtraObject.ExtraBool : false;
if (MyValue && !extraBool) {}

An alternative means of writing extraBool is:

var extraBool = window.ExtraObject && ExtraObject.ExtraBool;

You can then inline this:

if (MyValue && !(window.ExtraObject && ExtraObject.ExtraBool)) {}

An alternative of writing !(a && b) is !a || !b, which means that:

if (MyValue && (!window.ExtraObject || !ExtraObject.ExtraBool)) {}

is also correct.

* it could be MyValue===true depending on how strict you need to be
** alternatively typeof ExtraObject !== 'undefined'
*** it's not actually possible to have ExtraObject be undefined and access ExtraObject.ExtraBool

4 Comments

ok, thanks! I looked at it and I think your way of doing it is better than what I was doing with the "undefined" test. I upvoted your answer.
NO, actually your answer doesn't work in "strict mode". So my idea of working with the "undefined" test was actually good!
@frenchie, oh right, forgot to set it as window.ExtraObject, in which case it will work just fine.
AH YES! Global variables pollute the global scope for a reason. Thanks!
-1
if ((MyValue === true) && (typeof ExtraObject === undefined || ExtraObject.ExtraBool === false)) {}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.