Comparisons and Decisions
A program that does the same thing every time is only a list of steps. Programs become useful when they decide: open the menu if it is closed, close it if it is open, complain if the email field is empty. A decision needs two pieces: a comparison, which asks a question and gets true or false back, and an if statement, which picks what to run from the answer. JavaScript's decisions are straightforward. Its comparisons have a couple of famous traps, and they are worth meeting now, before real user input finds them for you.
An if statement works like a railway junction. The train reaches the points, the signals are checked in order, and the train takes exactly one branch: the first one showing green. It never takes two branches, and it never stays stuck at the junction.
Asking Questions: Comparisons
A comparison puts an operator, a symbol that works on values, between two values. Greater than and less than look the way they do in arithmetic. Greater than or equal is written as a greater-than sign followed by an equals sign, and less than or equal the same way round. "Is equal to" is written with three equals signs, and "is not equal to" with an exclamation mark followed by two equals signs. Every comparison answers with a boolean.
> 5 > 3 true > 2 >= 7 false > 5 === 5 true > 5 === "5" false > "css" !== "html" true
In the Console above, five is greater than three, so the answer is true. Two is not greater than or equal to seven: false. Five equals five: true. The fourth line is the one to look at twice. The number five and the string five are not equal, because three equals signs compare the type as well as the value. The last line asks whether the text css is different from the text html, and it is.
JavaScript also has a two-equals version, called loose equality. Before comparing, it converts both values to the same type, following rules that surprise almost everyone: with two equals signs, an empty string counts as equal to zero. This book uses three equals signs everywhere, and so should you. And one equals sign on its own is not a comparison at all: it is the assignment from the previous topic, which points a name at a value.
The Plus-Sign Trap
The plus sign has two jobs. Between two numbers it adds. Between two strings it joins them, one after the other. When one side is a string and the other a number, joining wins: the number is turned into text and stuck on the end. So the string five plus the number one gives the string fifty-one. The minus sign has only one job, subtraction, so the string five minus one gives the number four.
> "5" + 1 '51' > "5" - 1 4 > Number("5") + 1 6 > Number("five") NaN
This is more than a curiosity. Everything a visitor types into a form reaches your script as a string, even when it looks like a number; Chapter 10 comes back to that. Turn such text into a number with Number first, as on the third line, and adding works again: six. When the text is not a number at all, as on the last line, you get NaN, short for "not a number", a special value that means the conversion failed. One more catch: an empty string converts to zero, not to NaN, so check that a field is not empty before converting what is in it.
if, else if and else
An if statement is the word if, a condition in round brackets, and then a block of code in curly braces that runs only when the condition is true. An else if adds another condition to try when the first was false, and a final else catches everything left over.
const hour = new Date().getHours(); if (hour < 12) { console.log("Good morning"); } else if (hour < 18) { console.log("Good afternoon"); } else { console.log("Good evening"); }
The first line makes a record of the current date and time with new Date(), then reads only the hour from it with getHours: a whole number from 0 to 23. Then the decision. At ten in the morning, the hour is less than twelve, so the Console shows Good morning. At three in the afternoon, the hour is fifteen: the first check is false, the second is true, and the Console shows Good afternoon. At nine in the evening both checks are false, and the else block shows Good evening.
Look again at ten in the morning. The hour is also less than eighteen, but that second check is never even made: the first true branch wins, and the rest are skipped. That is why the order of the checks matters. Put the less-than-eighteen check first, and the morning greeting could never appear.
Truthy and Falsy
The condition in an if does not have to be a boolean. JavaScript treats every value as either true or false when it needs a decision. The values that count as false are called falsy, and there are only a handful: false, the number zero, the empty string, null, undefined and NaN. Two rarer forms of zero, negative zero and the zero of a special type for very large whole numbers, are falsy too; you will seldom meet either. Every other value is truthy, including the string zero and a string holding only a space.
That is handy: an if with a visitor's name as its condition runs only when the name is not empty. It is also a source of bugs whenever zero is a real answer. In the next block, the count of projects is known, and it happens to be zero.
const projectCount = 0; if (projectCount) { console.log(`Showing ${projectCount} projects.`); } else { console.log("Could not count the projects."); }
Could not count the projects.
The Console reports that the projects could not be counted, which is wrong: the count is there, it is zero. Zero is falsy, so the if took the wrong branch. The fix is to ask the question you actually mean. Here that is "is the count missing?", which is a comparison with undefined. With that condition, the Console shows Showing 0 projects.
const projectCount = 0; if (projectCount === undefined) { console.log("Could not count the projects."); } else { console.log(`Showing ${projectCount} projects.`); }
Combining Conditions
Three operators join or flip conditions. Two ampersands mean "and": both sides must be true. Two vertical bars mean "or": at least one side must be true. An exclamation mark in front of a condition means "not": it turns true into false and false into true. In the Console below, a shop opens at nine and closes at seventeen, and it is eight in the evening. Is it open? Nine or later and before seventeen: false. Is it closed? Before nine or seventeen or later: true.
> const hourNow = 20; undefined > hourNow >= 9 && hourNow < 17 false > hourNow < 9 || hourNow >= 17 true > !true false
- "One equals sign compares two values." One equals sign assigns: it points a name at a value. Comparing takes three.
- "Two equals signs are fine for everyday cases." They convert types before comparing, so an empty string equals zero. Use three equals signs everywhere and the question means what it says.
- "An empty list is falsy." An empty array, the list of Chapter 7, is truthy. To ask whether a list is empty, check how many items it has.
- Every interactive behaviour in this book is a decision: open or closed, valid or not, loaded or failed.
- The plus-sign trap and the three-equals rule prevent bugs that appear only when real people type real input.
Knowledge Check
What does 5 === "5" give?
- true, because both sides show the digit five
- false, because a number is never equal to a string
- An error, because the types do not match
- The string 55, because the two are joined
What does "5" + 1 produce?
- The number 6, from adding five and one
- The number 4, as the string is converted
- An error, since text and numbers differ
- The string 51, as the two are joined up
Which of these values is falsy?
- The string
"0", holding one digit - An empty array, with no items in it
- A string holding a single space character
- The number
0, written without quotes
With const hour = 9;, the code checks hour < 12, then hour < 18, then falls back to else. Which greeting appears?
- Good morning, from the very first branch
- Good afternoon, from the second branch
- Both the morning and afternoon greetings
- Good evening, from the else branch
You got correct