> For the complete documentation index, see [llms.txt](https://evie.gitbook.io/js/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://evie.gitbook.io/js/conditions.md).

# Understanding Conditions

A "condition" is a way to make certain parts of your code run *only* when specific criteria are met. When using conditions, you're creating a new block of code that runs, *or not*, depending on whether the condition returns a `true` or `false` value.&#x20;

Let's look at a very basic script that uses a condition.&#x20;

```javascript
const name = "Joe";

if( name === "Bob" ) {
  console.log("Hi Bob!");
} else {
  console.log(`Hello ${name}.`);
}
```

So here we have a condition that checks: "If the name is EXACTLY Bob, say hi to bob. Otherwise, say hi to whoever the hell this is". As a reminder, that fancy thing that says "hello, name." is a [Template Literal](/js/simple-data-types/template-literals.md).&#x20;

### Conditions are a Scope

I haven't really touched yet on "Scopes" in this page, but here's an important point about conditions: they create a new scope. What that means is that if you, for instance, define a variable inside a condition, it will not be available outside that condition:&#x20;

```javascript
if ( thingIsTrue ) {
  const blah = "Foo";
}
console.log(blah); // undefined
```

Keep that in mind when writing your conditions.&#x20;

### Conditions work with Booleans

A condition will always expect something that can be considered a Boolean value, that is to say, it evaluates to "true" or "false". It also will accept what we call "Truthy" and "Falsy" values which... Well, basically *everything* in JavaScript is truthy or falsy.&#x20;

Here's a few examples of things that can return literal `true` and `false`:&#x20;

* Loose Equal operator: `==` compares two values that can be of different types but, when compared with ==, have the same value. For example, `1 == "1"` returns `true`.&#x20;
* Strict Equal operator: `===` compares two values that must be of the same type. `1 === "1"` is `false`, but `1 === 1` is `true`.&#x20;
* Math operators such as `>` , `<` , `>=` and `<=`.&#x20;
* Boolean return functions: a whole lot of functions will return booleans of true and false. For example, [String.startsWith](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith) , [Array.includes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes), [Map.has](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has), [isNaN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN)... You'll notice that in those documentation pages, you can see that the **Return Value** is defined either as `true` or `false`, or as `Boolean`.&#x20;

As for truthy/falsy, the rule is actually pretty simple. Here is an exhaustive list of Falsy values:&#x20;

* `null` and `undefined`
* `0` (the number 0)
* Empty strings including `""`, `''`, empty template literals.
* `false` , of course.&#x20;
* `NaN` ("NotANumber")

Literally every single other thing in JavaScript is considered truthy. This includes functions and arrays, positive and negative numbers, Objects and Arrays (yes, even the empty ones).

Here's a couple of examples:&#x20;

```javascript
if ( 1 > 3 ) // false
if ( [] ) // true
if ( parseInt("Blah") ) // false
if ( 0 ) // false
if ( "true" ) // true
if ( "false" ) // true. This isn't a boolean value it's a string!
```

### Conditions can be Inverted

In the "Loose Equal" and "Strict Equal" operators above, I used `==` and `===` , to indicate that something should be equal. But what if I want it the other way around? How do I make something **NOT** equal? Well, anytime you think "not" in JavaScript, replace that with `!` in your code and you'll end up with the opposite boolean. To simplify this to the extreme:&#x20;

```javascript
!true // this equals false
!false // this equals true

!0 // true
!"Blah" // false
!undefined // true
```

### Conditions can be Combined

So what if you need to combine two conditions together? Of course you could do something like:

```javascript
if ( thing ) {
  if ( otherThing ) {
    doSomething();
  }
}
```

Looks pretty ugly, doesn't it? Well, there are ways to combine these things into a single condition, by using the AND (&&) and OR (||) operators.&#x20;

* `&&` means "**BOTH** must be true for the condition to return true"
* `||` means "**EITHER** can be true for the condition to return true"

The above can thus be written simply with:&#x20;

```javascript
if ( thing && otherThing ) {
  doSomething();
}
```

Combined conditions are read from left to right by default, unless you override that order with more parentheses. If you recall high school math, you might remember a little thing called the "Order of Operation", or "PEMDAS". In terms of conditions (not math), the important thign to remember is that the P is first, which means that parentheses always, *always* get parsed first.

Take a look at this more complex example:&#x20;

```javascript
if ( ( true && false ) || ( false || true ) ) {
  // this will run
}
```

So what's happening here?&#x20;

* First, `( true && false)` is evaluated. It returns `false` because the AND operator requires both to be true.
* Then , `( false || true )` is evaluated. It returns `true` because the OR operator allows either to be true.
* So we're now left with `(false || true )` which of course returns true because, read right above.
* In the end, `if(true)` obviously will let the code inside the condition run.&#x20;

{% hint style="warning" %}
Warning: While you might expect something like `if ( thing === 'one' || 'two' || 'three' )` to work... it doesn't. Because conditions convert everything to truthy/falsy values, you end up with `if( true || true || true)` or `if ( false || true || true)` and in both cases, the condition will run. There are ways around this sort of problem, such as Array.includes(), which you'll find in [Awesome Array Methods](/js/mid-level-data-types/awesome-array-methods.md).
{% endhint %}

One last note: conditions are always read left to right, and some optimization can be gained by understanding a very cute fact: ***If you have a bunch of OR operators, the first true value will stop the chain completely***. What I mean by this is that you should always order your conditions, if at all possible, from "most common" on the left, "less common" on the right. You should also make a check that's more CPU-intensive appear at the end of a condition chain, if you can avoid it with another condition.&#x20;

Let me explain with some code:&#x20;

```javascript
const veryIntensiveCheck = () => true; // imagine this takes 30 seconds to run.
const simpleCheck = () => true; // imagine this takes 10ms to run.

// This condition will take 30 seconds to return a value
if ( veryIntensiveCheck() || simpleCheck() ) {
  return true;
}

// This condition will return almost immediately after 10ms
if ( simpleCheck() || veryIntensiveCheck() ) {
  return true;
}
```

So, to re-iterate, the second version is faster because in a combined OR chain, if ANY of the condition is true, we know the entire chain should return true, so what's the point of even checking the rest? So it doesn't!

### Conditions can be Ternary

Ooooooh ternary conditions. A complicated word for such a simple and awesome concept. So in [Conditions are a Scope](/js/conditions.md#conditions-are-a-scope) , we saw that you can't define a variable inside a scope and use it outside. There's a way to get around this, which looks something like:

```javascript
let value;

if ( thingIsTrue ) {
  value = "yay";
} else {
  value = "booh";
}
// value works here
```

But... this is ugly as hell, is it not? It also means that in some complex code where you use many different variables, you might end up with a metric crapton of variables specifically created with the purpose of holding a temporary value, and being reassigned a new value right away. This will hurt both your performance and your brain, so let's start by making this a bit simpler, using the Ternary operator. Its use is super simple:&#x20;

```javascript
(condition) ? trueValue : falseValue;
```

A ternary always *returns* either the true or false value, which means it can be used in many different interesting ways. First off, it can simplify the example above:&#x20;

```javascript
const value = thingIsTrue ? 'yay' : 'nay';
```

But why even have this variable in the first place? As with a lot of things that return a value, they can be used directly in many ways.

* You can return them : `return someFunction() ? 'It Worked!' : 'Failure in function';`
* You can use them in objects: `{ value: check(blah) ? 'blah' : 'default' , otherValue: 'meh' }`
* You can even use them in functions like Array.map! `myArray.map(val => isOdd(val) ? 'odd' : 'even')`

With this in mind you should have a better time writing shorter, more elegant code when dealing with simple values.

### Condition Operators Overload

I'll be honest, I'm pulling this terminology out of my ass, but I haven't really seen a definitive name for this technique and those that exist are weak. It's sort of a different way to define a variable in a similar fashion to the Ternary above, but if you only have a `true` or `false` value and not the other. Let's see what I mean:&#x20;

```javascript
const myName = input.name || 'No Name';
const text = hasDetail(input) && `User Message: ${input.message}`;
```

So what's happening above, and why can we use this? It has to do with the chaining that was discussed in the Combining portion of this page. Simply put, when JavaScript sees a *false value on the left* operand followed by `||` , it continues down the chain, and will return the value on the right. If it sees a *true value on the left* followed by a `&&` it will also return the value on the right.

This means that in addition to knowing that *an OR condition chain will stop being evaluated on the first truthy value it finds*, we also know that in any condition chain, *the last value is always returned to the calling code*.&#x20;

There are some pretty damn nifty tricks you can do when you understand these 2 things correctly, but for the time being, I feel I've already filled your head with too much goobledygook so we'll leave it at that. Have fun conditioning your brain!
