Conditionals
Understanding Booleans
To understand conditionals (if, else if, else blocks) in JavaScript, you'll need a solid understanding of booleans first.
true
and false
Simply put, a Boolean only has two values it can be - true
or false
. These are reserved keywords in JavaScript and must be spelled/capitalized (not capitalized at all) correctly.
Examples:
var myBool = false;
var isThisASimpleConcept = true;
Conditions
The concept of conditions are pretty straight-forward, since they're actually part of our every day life (usually without realizing it, we're evaluating conditions just about every waking minute of our life).
For example, you probably evaluate a condition when you first wake up. You look at a clock to see what time it is, and if you woke up on time, you'll get ready at a leisurely pace, eat breakfast, etc. Otherwise (else) you'll rush to get ready.
The condition in this example is the time on the clock compared to the time you wish it were. In JavaScript, this might look like the following:
if (currentTime <= wakeUpTime) {
beLeisurely();
eatBreakfast();
} else {
rushOutTheDoor();
}
Anatomy of the conditional statement
You'll always start a conditional block with an if
statement, followed by parentheses and curly braces:
if (condition) {
// thing to do;
}
The computer's job is to check the part inside the parentheses and turn it into a boolean, either true
or false
.
If it is able to turn the condition into true
, it will run the code inside the if
block curly braces. If it turns it into a false
, it won't.
Comparison Operators
We usually don't know ahead of time the values of the things we're comparing. So we use comparison operators and equality operators to check the current status of different variables so that our program can make the correct decision on which code it should run.
Equality/inequality operators
===
checks that the operand on the left side is the same value and same data type as the operand on the left1 === 1
will evaluate totrue
"1" === 1
will evaluate tofalse
!==
checks that the operand on the left is NOT the same value or is not the same type as the operand on the right2 !== 2
evaluates tofalse
"2" !== 2
evaluates totrue
Comparison operators
>
returnstrue
if the left operand is greater than the right operand1 > 2
returnfalse
20 > 10
returnstrue
<
returnstrue
if the left operand is less than the right operand3 < 4
returnstrue
>=
and<=
returntrue
if the left is greater than or equal to or less than or equal to the right, respectively.5 >= 5
returnstrue
6 <= 7
returnstrue
A (kind of) practical example:
For example, let's say we only want to allow children under 18 to use our website. The first thing we do when the page loads is pop up a box asking the user's age. Then, if the number they input is less than 18, we continue to load the site. Otherwise (else) we tell them they're too old to be here.
var age = parseInt(prompt("What is your age?"));
if (age <= 17) {
// Allow the user in
} else {
// Don't allow the user in
}
"Truthy" vs. "Falsey"
Sometimes in your code the computer can't simply turn a value into a boolean directly. If it sees if(true || false)...
it knows how to turn the true || false
into a boolean (true
). But what if you have: if (42) {...}
?
The terms "truthy" and "falsey" refer to values that the computer can infer true
or false
from, even if they aren't booleans. Remembering what is "truthy" and what is "falsey" is pretty straight forward.
"Falsey" values in JavaScript:
false
(naturally)0
""
(empty string)null
undefined
NaN
(Not a Number)
"Truthy" values in JavaScript:
- Everything else
Examples:
var myArray = [];
if(myArray.length) {
// won't run because myArray.length is 0, and that is a falsey value.
}
if (myArray) {
// WILL run, because an empty array isn't one of the falsey values.
}
Logic operators
Sometimes we need to compare multiple things before knowing we want to run a certain block of code. Let's say, for example, that we created a website only for people named "Felix" who are older than 12 years old. As such, when the user creates their account we only want to allow them to create their account if their first name is "Felix" AND if their age is greater than or equal to 12. We need a way to combine comparisons, and that's where logic operators come in to play.
And (&&
)
The double ampersand (&&
) requires that the value on the left AND the value on the right of the &&
both evaluate to true
in order for the whole expression to be considered true
. As such:
false && false
evaluates tofalse
false && true
evaluates tofalse
true && false
evaluates tofalse
true && true
is the only one that evaluates totrue
So, for example:
(1 > 3) && (false); // false
(5 < 3) && (true); // false
(1 < 3) && (false); // false
(1 < 3) && (true); // true
Advanced reading about
&&
- The above explanation of the&&
operator will help you understand about 99.9% of the&&
s you see. If this is your first time learning this stuff, feel free to move on.
However, there's a little more to the
&&
operator. What it really does, rather than evaluate both sides to atrue
orfalse
is it returns the first value if it is falsey and stops evaluating the rest of the expression, OR it will return the second value if the first value is truthy.
true && true => true (we knew this)
4 && 5 => 5 (Because 4 is a truthy value, the && returns the second value, which is 5, a truthy value. So `if(4 && 5){...}` will pass the conditional test
0 && 5 => 0 (First value is falsey, so it returns that value immediately, and conditionals using this will fail)
"" && false => "" (empty string is also falsey; conditionals fail)
This concept can be particularly useful in assuring that a function or method exists before trying to call it. Rather than typing:
if (person.speak !== undefined) {
person.speak();
}
You can instead just do:
person.speak && person.speak();
If
person.speak
is undefined, it will stop evaluating that expression and not evaluate the method call. If it is truthy, it will call the method from the second part of the statement.
If that didn't make any sense to you, don't worry about it. Revisit this page at a later time and it might start to click.
Or (||
)
The double pipe (||
) allows either the value on the left OR the value on the right of the ||
to evaluate to true
in order for the whole expression to be considered true
. As such:
true || true
evaluates totrue
false || true
evaluates totrue
true || false
evaluates totrue
false || false
is the only one that evaluates tofalse
So, for example:
(1 > 3) || (false); // false
(5 < 3) || (true); // true
(1 < 3) || (false); // true
(1 < 3) || (true); // true
Not (!
)
Any expression or simple boolean can be reversed with the !
("not") operator. For example:
console.log(!true); // false
console.log(!false); // true
console.log(!true || false); // false
console.log(!(1 > 3) || !true); // ==> !false || !true ==> true || false ==> true
Order of operations
It's important to note that the logical operators will execute in a pre-determined order of operations, similar how +
, -
, *
, ÷
, etc. in math have an order of operations.
There is a long list of point values associated with operations which you can find on MDN's Operator Precedence Table, but here are the ones we're most concerned with when talking about conditions:
- Grouping using parentheses -
()
- Not operator -
!
- Logical And -
&&
- Logical Or -
||
Here are some examples to illustrate the importance of understanding the order of operations.
!true || true; // ==> false || true == > true
!(true || true); // ==> !(true) ==> false
!(!false && (true || false) || !(false || false)); // ==> !(true && true || !(false)) ==> !(true || false) ==> !true ==> false
Example
In our above example about the website where we only want to allow people whose name is Felix AND who is 12 or older, we could find ourselves writing something like the following:
var age = parseInt(prompt("What is your age?"));
var name = prompt("What is your name?").toLowerCase();
if (age <= 12 && name === "felix") {
// Welcome!
} else {
// Go away!
}
Switch statements
If you find yourself wanting to write a long chain of if
, else if
, else if
, else if
, else if
etc. statements, you can shorten and simplify your chain by using a switch
statement.
switch
looks at a variable and tests it against a number of "cases". If the variable matches the case, it executes the code inside the case:
block. It's important to use break
after each case unless you want it to continue checking other cases as well.
You also will always want to add a default
case at the end to act as an else
, in case all of the above cases
don't match.
switch (mood_ring) {
case ‘blue’:
mood = ‘calm’;
break;
case ‘red’:
mood = ‘excited’;
break;
default:
mood = ‘dead’;
}
Ternary operator
The ternary operator gives us a way to shorten a common if(){}
block:
if (moodRing == "blue") {
mood = "calm";
}
It works like this:
variableToSet = (conditionToCheck) ? <value if the condition is true> : <value if the condition is false>
Using the ternary operator (?
) we can shorten this to:
mood = (moodRing === "blue") ? "calm" : mood;
What's the deal with ==
vs. ===
?
First of all, as a general rule, you should always plan on using ===
instead of ==
.
Both ==
and ===
will check to make sure the value of the two operands are the same. The difference is that ===
will also check to make sure the type of the two operands are the same. ==
on the other hand will attempt to coerce the two operands into the same data type. Since this can have some strange side effects, it's always best to use ===
and be sure you're getting a correct equality.
// Double equals (==)
"0" == 0 // true
"" == "0" // false
0 == "" // true
false == undefined // false
false == null // false
null == undefined // true
// Triple equals (===)
"0" == 0 // false
"" == "0" // false
0 == "" // false
false == undefined // false
false == null // false
null == undefined // false
As you can see, the ===
behaves more like you'd expect it to, without relying on JavaScript to do too much of your job as a developer for you. (Like making sure types are equal before comparing them).