Applying Comparison and Logical Operators - JavaScript Basics - JavaScript, 20 Lessons to Successful Web Development (2015)

JavaScript, 20 Lessons to Successful Web Development (2015)

PART I JavaScript Basics

LESSON 4 Applying Comparison and Logical Operators

image

To view the accompanying video for this lesson, please visit mhprofessional.com/nixonjavascript/.

The arithmetic and string operators you have so far seen are fundamental to manipulating data inside computers. But without the ability to test things and make decisions, computers would be little more than advanced calculators. However, when you bring comparison and logical operators into the equation, you begin to expand the JavaScript language into a form with which complex tasks can be broken down, analyzed, and implemented.

Combining these with the arithmetic and string operators, you then have most of the basic features of a programming language, and from this point you simply extend the language by adding the ability to control program flow (as explained in Lesson 10), including data structures such as arrays (see Lesson 5), supporting sequences of instructions in functions (see Lesson 12), or offering even greater abstractions such as creating objects containing both data and program code (as explained in Lesson 13).

Therefore, once you have finished this lesson, you will already be programming at a basic level.

Comparison Operators

One of the most important processes that happens in a program is comparison. For example, possibly the most frequent type of construct used goes along the lines of if this then do that. The job of comparison operators is to figure out the this part, and there are eight of them, as listed in Table 4-1.

TABLE 4-1 The Comparison Operators

image

Figure 4-1 shows several different comparison operators used on different values and the results obtained. It was created using the file comparison_operators.htm, available in the companion archive.

image

FIGURE 4-1 A selection of comparison operators in use

If you haven’t programmed before, some of these operators may seem a little confusing, especially seeing as we are taught as children that = is the equal to operator. However, in programming languages such as JavaScript, the = is used as an assignment operator, and therefore code would become harder to read (and the writers of programming languages would have a much harder time figuring out its meaning) if the = symbol were also used to make comparisons. Therefore, the == operator is used for comparisons instead, like this:

if (a == 12) // Do something

In JavaScript, however, the types of variables are loosely defined and it’s quite normal, for example, to ask whether the number 1 is the same as the string ′1′, because the string ′1′ can be used either as a string or as a number depending on the context. Therefore, the following expression will return the value true:

if (1 == ′1′) // Results in the value true

image

JavaScript uses the internal values of true and false to represent the result of making comparisons such as the preceding, and you can use the keywords true and false in your programming to check for these values.

Progressing through the list of comparison operators, when you wish to determine whether two values are the same value and also of the same type, you can use the === operator, like this:

if (1 === ′1′) // Results in the value false

Similarly, you can test whether values are not equal (but not comparing the type) using the != operator, like this:

image

And if you wish to check whether two values are not equal in both value and type, you use the !== operator, like this:

if (1 !== ′1′) // Results in the value true

The remaining comparison operators test whether one value is greater than, less than, greater than or equal to, or less than or equal to another, like this:

image

Logical Operators

JavaScript supports three logical operators with which you can extend your if this parts of code even further, as listed in Table 4-2.

TABLE 4-2 The Logical Operators

image

Figure 4-2, created using the file logical_operators.htm from the companion archive, shows these operators being used in expressions.

image

FIGURE 4-2 Using logical operators

The && operator (known as the and operator) allows you to test for multiple conditions being true, saving you from having to write multiple lines of code by combining them into a single expression, like this:

if (a == 4 && b == 7) // Do this

In this example, the statement following the if() (just a comment in this instance) will be executed only if a has a value of 4 and also b has a value of 7. Or you can test whether at least one value is true using the || operator (known as the or operator), like this:

if (a == 4 || b == 7) // Do this

Here if either a has the value 4 or b has the value 7, the statement after the if() will be executed, so only one of the expressions needs to evaluate to true. Finally, you can negate any expression using the ! symbol (known as the not operator) by placing it in front of the expression (generally placing the expression within parentheses too, so that the ! applies to the entire expression instead of only to a part of it), like this:

if (!(game == over)) // Carry on playing

In this example, if the variable game contains the same value as the variable over, the result of the expression is true. Then the ! operator negates this to turn that value into false. Therefore, the statement after the if() will not be executed.

On the other hand, if game is not equal to over, the expression evaluates to false, which is negated to true, and so the code after the if() is executed. Therefore, the expression equates to the semi-English sentence “If not game over then do this.”

image

When an expression can only return either a true or false value, it is known as a Boolean expression. When combined with and, or, and not (&& and || and !), such expressions are said to use Boolean logic.

The Ternary Operator

Ever on the lookout for ways to make program code simpler and more compact, program language developers also came up with a thing called the ternary operator, which allows you to combine “If this then do that thing otherwise do another thing” type logic into a single expression, like this:

document.write(game == over ? ′Game over’ : ’Keep playing′)

The way the ternary operator works is that you provide an expression that can return either true or false (a Boolean expression). Following this, you use a ? character, after which you place the two options, separated with a : character, as follows:

expression ? do this : do that

For example, another ternary expression might go like the following, which sets the string variable AmPm to either AM or PM, according to the numeric value in the variable Time:

AmPm = Time < 12 ? ′AM′ : ′PM′

Bitwise Operators

There is a type of operator supported by JavaScript that as a beginner to programming you are most unlikely to use, due to it being quite advanced, and that’s the bitwise operator. This type of operator acts on the individual 0 and 1 bits that make up binary numbers, and can be quite tricky to use.

The bitwise operators are &, |, ^, ~, <<, >>, and >>>. In order, they support bitwise and, or, exclusive or, not, left-shift, sign-propagating right-shift, and zero-fill right-shift on binary numbers.

The bitwise operators can be combined with the = assignment operator to make a whole new collection of bitwise assignment operators.

However, this is a basic book on JavaScript and not an advanced tutorial, so I won’t go into how you use them, because you already have enough new stuff to learn as it is. But for the curious who would like to know more about them, you can check out the following web pages, which cover them in some detail:

tinyurl.com/bitwiseops

tinyurl.com/bitwiseops2

Operator Precedence

In JavaScript some operators are given a higher precedence than others. For example, multiplication has a higher precedence than addition, so in the following expression the multiplication will occur before the addition, even though the addition appears first:

3 + 4 * 5

The result of this expression is 23 (4 × 5 is 20, 3 + 20 is 23). But if there were no operator precedence (with the expression executed simply from left to right), it would evaluate to 35 (3 + 4 is 7, 7 × 5 is 35).

By providing precedence to operators, it obviates the need for parentheses, because the only way to make the preceding expression come out to 23 without operator precedence would be to insert parentheses as follows:

3 + (4 * 5)

With this concept in mind, the creators of JavaScript have divided all the operators up into varying levels of precedence according to how “important” they are (in that multiplication is considered more “important” than addition due to its greater ability to create larger numbers). For the same reason, division is given greater precedence than subtraction, and so on.

Therefore, unless you intend to use parentheses in all your expressions to ensure the correct precedence (which would make your code much harder to write and for others to understand, due to multiple levels of parentheses), you need to know these precedencies, which are listed in Table 4-3.

TABLE 4-3 Operator Precedence

image

There are quite a few operators in this table that you have not yet seen. Some of which (such as the bitwise operators) will not be covered, and others (such as in, typeof, and so on) will be explained later in the book.

All you need to learn from this table, though, is which operators have higher precedence than others, where 1 is the highest and 17 is the lowest precedence, and where an operator has lower precedence but you need to elevate it, all you need to do is apply parentheses in the right places for the operators within them to have raised precedence.

image

The unary+ and unary- entries in Table 4-3 represent the use of placing either a + before an expression to force it into being used as a number or placing a - sign in front of an expression to negate it (change a negative value to positive or vice versa). The comma operator (at a precedence of 17) is used as an expression or argument separator, so it naturally has the lowest precedence.

Operator Associativity

JavaScript operators also have an attribute known as associativity, which is the direction in which they should be evaluated. For example, the assignment operators all have right-to-left associativity because you are assigning the value on the right to the variable on the left, like this:

MyVar = 0

Because of this right-to-left associativity, you can string assignments together, setting more than one variable at a time to a given value, like this:

MyVar = ThatVar = OtherVar = 0

This works because associativity of assignments starts at the right and continues in a leftward direction. In this instance, OtherVar is first assigned the value 0. Then ThatVar is assigned the value in OtherVar, and finally MyVar is assigned the value in ThatVar.

On the other hand, some operators have left-to-right associativity, such as the || (or) operator. Because of left-to-right associativity, the process of executing JavaScript can be speeded up, as demonstrated in the following example:

if (ThisVar == 1 || ThatVar == 1) // Do this

When JavaScript encounters the || operator, it knows to check the left-hand side first. Therefore, if ThisVar has a value of 1, there is no need to look up the value of ThatVar, because as long as one or the other expressions on either side of the || operator evaluates to true, then the entire|| expression evaluates to true, so if the left half has evaluated to true, then so has the entire || expression. In cases such as this, the JavaScript interpreter will eagerly skip the second half of the expression, knowing it is running in an optimized fashion. By the way, in programming language theory, this is called lazy evaluation.

Knowing whether operators have right-to-left or left-to-right associativity can really help your programming. For example, if you are using a left-to-right associative operator such as ||, you can line up all your expressions left to right from the most to the least important.

Therefore, it is worth taking a moment to familiarize yourself with the contents of Table 4-4 so that you will know which operators have what associativity.

TABLE 4-4 Operator Associativity

image

The with Keyword

Using JavaScript’s with keyword, you can simplify some types of JavaScript statements by reducing many references to an object to a single reference. For example, in the following code, the document.write() function never references the variable string by name:

image

Even though string is never directly referenced by document.write(), this code still manages to output the following:

The string′s length is 43 characters
Upper case: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG

The way this works is that the JavaScript interpreter recognizes that the length property and the toUpperCase() method have to be applied to some object, but because they stand alone, the interpreter assumes they must apply to the string object specified in the with statement.

image

The very fact that assumptions about which object to apply the with to have to be made by the interpreter can make its use ambiguous in some applications. Therefore, I would generally recommend that you try to avoid working with this statement unless you feel confident that you can use it without ambiguity.

Summary

This lesson has brought you up to speed with all you need to know about using operators, so now you’re ready to start looking at some of JavaScript’s more complex and interesting objects in the following lesson on arrays.

Self-Test Questions

Test how much you have learned in this lesson with these questions. If you don’t know an answer, go back and reread the relevant section until your knowledge is complete. You can find the answers in Appendix A.

1. Which operator is used to check whether two values are equal?

2. What is the difference between the == and the === operators?

3. What values can a comparison expression evaluate to?

4. Which operator would you use to test whether two values (or expressions) are both true?

5. Which operator would you use to test whether at least one of two values (or expressions) is true?

6. With which operator can you test whether a value (or expression) is not true?

7. Which operator out of * and + has the highest precedence and will be evaluated first?

8. Which operator has the lowest precedence of all?

9. In which direction do the mathematical operators *, /, +, and – evaluate from?

10. How can you shorten code by removing repeated uses of an object’s name?