Primitive Data Types, Arrays, Loops, and Conditions: Part 3 [con't]
Checking if a Variable Exists
It's often useful to check whether a variable exists. The laziest way to do this is simply putting the variable in the condition part of the if
, for example if (somevar) {...}
, but this is not necessarily the best method. Let's take a look at an example that tests whether a variable called somevar
exists, and if so, sets the result
variable to yes
:
This code obviously works, because at the end result
was not "yes". But firstly, the code generated a warning: somevar is not defined and as a JavaScript whiz you don't want your code to do anything like that. Secondly, just because if (somevar)
returned false
doesn't mean that somevar
is not defined. It could be that somevar
is defined and initialized but contains a falsy value, like false
or 0.
A better way to check if a variable is defined is to use typeof
.
typeof
will always return a string and you can compare this string with "undefined
". Note that the variable somevar
may have been declared but not assigned a value yet and you'll still get the same result. So when testing with typeof
like this, you're really testing whether the variable has any value (other than the value undefined
).
If a variable is defined and initialized with any value other than undefined
, its type returned by typeof
is no longer "undefined".
Alternative if Syntax
When you have a very simple condition you can consider using an alternative if
syntax. Take a look at this:
The if
condition can be expressed simply as:
You should only use this syntax for very simple conditions. Be careful not to abuse it, as it can easily make your code unreadable.
The ?
is called ternary operator.
Switch
If you find yourself using an if
condition and having too many else if
parts, you could consider changing the if
to a switch
.
The result of executing this will be "String 1". Let's see what the parts of a switch
are:
- The
switch
statement. - Some expression in parentheses. The expression most often contains a variable, but can be anything that returns a value.
- A number of case blocks enclosed in curly brackets.
- Each
case
statement is followed by an expression. The result of the expression is compared to the expression placed after theswitch
statement. If the result of the comparison istrue
, the code that follows the colon after thecase
is executed. - There is an optional
break
statement to signal the end of the case block. If thisbreak
statement is reached, we're all done with the switch. Otherwise, if thebreak
is missing, we enter the nextcase
block, which should be avoided. - There's an optional
default
statement, which is followed by a block of code that is executed if none of the previous cases evaluated totrue
.
In other words, the step-by-step procedure for executing a switch
statement is as follows:
- Evaluate the switch expression found in parentheses, remember it.
- Move to the first case, compare its value with the one from step 1.
- If the comparison in step 2 returns
true
, execute the code in thecase
block. - After the
case
block is executed, if there's abreak
statement at the end of it, exit the switch. - If there's no
break
or step 2 returnedfalse
, move on to the nextcase
block. Repeat steps 2 to 5. - If we're still here (we didn't exit in step 4), execute the code following the
default
statement.
Best Practice Tips
- Indent the
case
line, and then further indent the code that follows it. - Don't forget to
break
. Sometimes you may want to omit thebreak
intentionally, but that's rare. It's called a fall-through and should always be documented because it may look like an accidental omission. On the other hand, sometimes you may want to omit the whole code block following a case and have two cases sharing the same code. This is fine, but doesn't change the rule that if there's code that follows acase
statement, this code should end with abreak
. In terms of indentation, aligning thebreak
with thecase
or with the code inside the case is a personal preference; again, being consistent is what matters. - Use the
default
case. This will help you make sure you have a meaningful result after the switch, even if none of the cases matched the value being switched.
Loops
if-else
and switch
statements allow your code to take different paths, as if you're at a crossroads and decide which way to go depending on a condition. Loops, on the other hand, allow your code to take a few roundabouts before merging back into the main road. How many repetitions? That depends on the result of evaluating a condition before (or after) each iteration.
Let's say you are (your program execution is) traveling from A to B. At some point, you reach a place where you evaluate a condition C. The result of evaluating C tells you if you should go into a loop L. You make one iteration. Then you evaluate the condition once again to see if another iteration is needed. Eventually, you move on your way to B.
An infinite loop is when the condition is always true and your code gets stuck in the loop "forever". This is, of course, is a logical error and you should look out for such scenarios.
In JavaScript, there are four types of loops:
while
loopsdo-while
loopsfor
loopsfor-in
loops
While Loops
while
loops are the simplest type of loop. They look like this:
The while
statement is followed by a condition in parentheses and a code block in curly brackets. As long as the condition evaluates to true
, the code block is executed over and over again.
Do-while loops
do-while
loops are a slight variation of the while
loops. An example:
Here, the do statement is followed by a code block and a condition after the block. This means that the code block will always be executed, at least once, before the condition is evaluated.
If you initialize i
to 11 instead of 0 in the last two examples, the code block in the first example (the while
loop) will not be executed and i
will still be 11 at the end, while in the second (do-while
loop), the code block will be executed once and i
will become 12.
For Loops
for
is the most widely used type of loop and you should make sure you're comfortable with this one. It requires a just little bit more in terms of syntax.
In addition to the condition C and the code block L, you have the following:
- Initialization—some code that is executed before you even enter the loop (marked with 0 in the diagram)
- Increment—some code that is executed after every iteration (marked with ++ in the diagram)
The most widely used pattern of using a for
loop is:
- In the initialization part you define a variable, most often called
i
, like this:var i = 0;
- In the condition part you compare
i
to a boundary value, likei
- In the increment part, you increase
i
by 1, likei++
Here's an example:
All three parts (initialization, condition, increment) can contain multiple expressions separated by commas. You can rewrite the example and define the variable punishment
inside the initialization part of the loop.
Can you move the body of the loop inside the increment part? Yes, you can, especially as it's a one-liner. This will give you a loop that looks a little awkward, as it has no body:
These three parts are actually all optional. Here's another way of rewriting the same example:
Although the last rewrite works exactly the same way as the original, it is longer and harder to read. It's also possible to achieve the same result by using a while
loop. But for
loops make the code tighter and more robust, because the mere syntax of the for
loop makes you think about the three parts (initialization, condition, increment) and thus, helps you reconfirm your logic and avoid situations such as being stuck in an infinite loop.
for
loops can be nested within each other. Here's an example of a loop that is nested inside another loop and assembles a string containing 10 rows and 10 columns of asterisks. Think of i
being the row and j
being the column of an "image".
Here's another example that uses nested loops and a modulus operation in order to draw a little snowflake-like result.
For-in Loops
The for-in
loop is used to iterate over the elements of an array (or an object, as we'll see later). This is its only use; it cannot be used as a general-purpose repetition mechanism that replaces for
or while
. Let's see an example of using a for-in
to loop through the elements of an array. But bear in mind that this is for informational purposes only, as for-in
is mostly suitable for objects, and the regular for
loop should be used for arrays.
In this example, we'll iterate over all of the elements of an array and print out the index (the key) and the value of each element:
The result
is:
Comments
One last thing for this chapter: comments. Inside your JavaScript code you can put comments. These are ignored by the JavaScript engine and don't have any effect on how the program works. But they can be invaluable when you revisit your code after a few months, or transfer the code to someone else for maintenance.
Two types of comments are allowed:
- Single line comments—start with
//
and end at the end of the line - Multi-line comments—start with
/*
and end with*/
on the same line or any subsequent line. Note that any code in between the comment start and the comment end will be ignored.
Some examples:
There are even utilities, such as JSDoc, that can parse your code and extract meaningful documentation based on your comments.
Summary
In this chapter, you learned a lot about the basic building blocks of a JavaScript program. Now you know the primitive data types:
- number
- string
- boolean
- undefined
- null
You also know quite a few operators:
Arithmetic operators:+
, -
, *
, /
, and %
.
Increment operators: ++
and --
.
Assignment operators: =
, +=
, -=
, *=
, /=
, and %=
.
Special operators: typeof
and delete
.
Logical operators: &&
, ||
, and !
.
Comparison operators: ==
, ===
, !=
, !==
, <
, >
, >=
, and <=
.
Then you learned how to use arrays to store and access data, and finally you saw different ways to control the flow of your program—using conditions (if-else
or switch
) and loops (while
, do-while
, for
, for-in
).
This chapter is an excerpt from the book, Object-Oriented JavaScript by Stoyan Stefanov, published by Packt Publishing Ltd, July 2008, ISBN 1847194141, Copyright 2008 Packt Publishing Ltd
Original: August 18, 2008