Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

In javascript is there really a good reason to never check for boolean true || false such as if(var){}else{}?

+1
−0

I am fairly certain this isn't a duplicate so please bear with me.

I check for boolean true||false using if() as a matter of course in my programming. I've programmed extensively in PHP, some in C# ASP.NET, a bit in Java, a long time ago in C++, & dabled in a few others. Checking for boolean true||false has always been pretty straightforward (as far as I could tell). But in JavaScript I've heard, read, and otherwise been told it's bad. That instead of:

if(var){}else{}

I should instead do:

if(typeof(var) !== 'undefined' || typeof(var) !== null || var !== ''){}else{}

Previous to the six months prior to asking this question (originally on StackOverflow) I was a dabbler in JavaScript. After getting tired of writing & re-writing the long version of the boolean test shown above I finally asked a friend who's done extensive js development for years. My friend supported what I'd read, that I should never test for boolean true or false the way I'm used to. However, after that discussion I have a stronger belief that if(var){}else{} IS actually completely fine in js as it works EXACTLY like I would intuitively expect it to (my jsfiddle testing this)

I've looked around and found various links. The following seemed to be the more relevant:

The thing that convinced me most that my usage is safe and will work fine is the 3rd answer to the first SO question I linked to above given by Incognito. The js spec is very clear about what will & will not evaluate to boolean true||false, and again this is exactly as I would have expected (though have to be reminded that an empty array is an object... but that is specific to JavaScript, while the rest of it is exactly as I would expect).

Can someone please provide a definitive reason to not check for boolean true or false in JavaScrpt, realizing I know the difference between a boolean check and an equality check??

Thanks in advance!

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

3 answers

You are accessing this answer with a direct link, so it's being shown above all other answers regardless of its score. You can return to the normal view.

+0
−0

As mentioned in another answer, when you have code such as if (someVar), you're subject to truthiness. To be more precise, this code will run under the rules of Boolean coercion.

In JavaScript, when you have if (someVar), the variable someVar can be basically "anything" - even a boolean value! If someVar is not a boolean, it'll be converted according to some rules:

  • Booleans are returned as-is.
  • undefined turns into false.
  • null turns into false.
  • 0, -0, and NaN turn into false; other numbers turn into true.
  • 0n turns into false; other BigInts turn into true.
  • The empty string "" turns into false; other strings turn into true.
  • Symbols turn into true.
  • All objects become true.

A little test to check this behaviour:

function test(someVar) {
    if (someVar) {
        console.log(someVar, typeof someVar, 'true');
    } else {
        console.log(someVar, typeof someVar, 'false');
    }
}

for (const v of [ null, undefined, 0, 1, '', 'abc', [], [1, 2], {} ]) {
    test(v);
}

Output:

null object false
undefined undefined false
0 number false
1 number true
 string false
abc string true
[] object true
[ 1, 2 ] object true
{} object true

Note that any object is type-coerced to true1 (even an empty array or empty object).

  1: Except, of course, null (which is an object - although it shouldn't - but it's coerced to false)


Now back to the question: how should I check for a boolean value?

It depends!

If you know that someVar is a boolean value (either true or false, nothing else, and that's guaranteed in another part of the code), then if (someVar) is the most straighforward way to check it. You don't need anything else to verify if the value is true or false.

On the other hand, if you don't know what type someVar is (or you know, and it can be either a boolean or some other type), and you want to check if the type is boolean, then you could do something like this:

function checkBoolean(someVar) {
    if (typeof someVar === 'boolean' && someVar) {
        console.log('true');
    } else {
        console.log('false or not boolean');
    }
}

But in this case, if someVar is false, it'll enter the else clause (it's a boolean, but it's not true). If you want to differentiate between true, false and "anything else", then it should be:

function checkBoolean(someVar) {
    if (typeof someVar === 'boolean') { // it's a boolean value
        // it's either true or false
        if (someVar) {
            console.log('true');
        } else {
            console.log('false');
        }
    } else { // it's not a boolean
        console.log('not boolean');
    }
}

But if you don't care about the type of someVar and just want to know if it's "true" or "false" (according to the language's type coercion rules), if (someVar) is enough.

And of course, if you need a different check (such as "I want empty arrays to be false"), then just change the clause accordingly (ex: if (Array.isArray(someVar) ? someVar.length > 0 : someVar) - if it's an array, it can't be empty, otherwise check for truthiness).

Anyway, you must define exactly what you need: check if the type is boolean, or if the type-coerced value is true/false, or anything else (ignore null and undefined, or empty arrays can't be true, etc). Then you change the code accordingly.


Regarding the suggested code

IMO, if (typeof(someVar) !== 'undefined' || typeof(someVar) !== null || someVar !== '') is not a good way to check boolean values. Actually, I believe there's an error in this code. For example, if someVar is null, it enters the if clause:

const someVar = null;
if (typeof(someVar) !== 'undefined' || typeof(someVar) !== null || someVar !== '') {
    console.log('ok');
} else {
    console.log('not ok');
}

This code prints "ok", because typeof(null) is not null.

I believe that typeof(someVar) !== null is wrong, because it doesn't make sense: typeof anything will never be null (according to the language specification, the result of typeof is always a string).

Actually, it's worse: even if someVar is undefined or the empty string, this code will print "ok". That's because typeof(someVar) is never null, thus the condition typeof(someVar) !== null is always true. Therefore, this code is not checking anything.

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.

1 comment thread

Even if you replace `typeof someVar !== null` with `someVar !== null`, it still won't work. The condi... (1 comment)
+6
−0
if(typeof(var) !== 'undefined' || typeof(var) !== null || var !== ''){}else{}

is a wild thing to write for anything other than a variable that takes either undefined, null, or a string as possible values.

If you expect someVar to be a boolean, I don't know who would tell you that if (someVar) { ... } is incorrect.

If you expect someVar to be a boolean or null or undefined, or you expect it to be some other non-boolean type, then there's an argument for some sort of explicit coverage. People reading if (someVar) { ... } may expect someVar to be a boolean, even though JavaScript allows it to be other things. So if you want to express that someVar is a string, it's arguably better to write if (someVar !== '') { ... } then if (someVar) { ... } in order to make that expectation clear, even though they do the same thing. Similarly, if someVar may be a boolean or null, writing if (someVar === false || someVar === null) { ... } is clearer than if (!someVar) { ... }.

These are choices that will affect how some other people will read your code, and not what the machine will do. Programming is an act of communication and not just the puzzle of getting the machine to do the thing you want. Even the code you never share with others might be read by you five years later, and you'll be grateful then for the work you do now to save that you some time.

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.

1 comment thread

> Programming is an act of communication and not just the puzzle of getting the machine to do the thi... (1 comment)
+2
−0

r~~'s answer is good, and I absolutely agree that the condition provided in the question is ridiculous and I've never seen anyone suggest it as a generic replacement for if(var). But I think the actual advice that is being communicated (perhaps poorly) which is not explicitly called out in r~~'s answer is simply: "Avoid relying on truthiness." Or, more generally, ad-hoc implicit conversions.

This rule means that any boolean test should only be performed on booleans. By this rule, if(var) is completely fine so long as you know var is a boolean value. This rule suggests that you should almost never use == and should instead prefer === (similarly for != and !==). This rule implies that null and undefined should be treated as distinct values from true and false and should be tested for more explicitly. Something like this is presumably part of what led to the condition you posted, though this rule does not imply that particular condition (and that condition is unnecessarily complicated anyway). This rule definitely rules out broken, old-school patterns like someVar = someParam || SOME_DEFAULT intended to set someVar to a default value, SOME_DEFAULT, if someParam is not set.

Practically, it's very easy for some value you expect to (only) be a boolean to actually allow non-boolean values, particularly null and undefined. To that end, I highly recommend using TypeScript[1] with the strictest settings possible. While TypeScript does allow you to rely on truthiness (though you can use tslint's strict-boolean-expressions to warn about this), if you declare a variable as having type boolean, it will catch the very many ways such variables could fail to be bound to boolean values. In other words, this is an effective way of actually knowing whether some variable is a boolean value.

My post doesn't justify this rule, but the posts you link and many, many others illustrate the unintuitive behavior and mistakes using truthiness leads to.


  1. Or, at least, some other JavaScript type checking approach, though TypeScript is the one I'd recommend and seems to have "won". ↩︎

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.

0 comment threads

Sign up to answer this question »