1. Intro to Programming

An introduction to computer programming with JavaScript examples, written for students of CGS 3066: Web Programming & Design. Most of this document would be applicable and useful to anyone, including especially those who have never seen programming. It is meant to be read sequentially, although skipping around is possible.

If you have no idea how websites work or what JavaScript is, here is some direction. JavaScript is a programming language which is used to give websites interactive behavior, such as in pop-up messages, the photo-tagging feature on Facebook, the interactive buttons in Gmail, and even games that are embedded in web pages. JavaScript is everywhere. To get started without knowledge of websites, you might try going to jsFiddle first, typing in some code like document.write(2 + 2); in the JavaScript area, and pressing the Run button. Read the other sections of Getting started with JavaScript for some other peripheral tips. You may also want to try the Programmin' Playground, which was made for CGS 3066 and is bundled with those course materials. If you have access to that, just unzip the file, open the playground.html page, and read its instructions; you will soon want to edit the theScript.js file in order to insert new JavaScript. Using a text editor like Notepad++ is very helpful.

Table of Contents
  1. Intro to Programming
  2. Programming languages
  3. Getting started with JavaScript
  4. Common programming patterns
  5. JavaScript's features

1.1. The concept of programming

Computer programming is writing instructions for a computer to execute. We have seen some computer languages in making websites so far, but, strictly speaking, these may not be considered programming languages, because they lack a key component: a sequential flow of logical and mathematical instructions. We have described which text we want the web page to have and how it should look, but we have not given a series of steps to be executed.

Computer programs are actually analogous to flow charts. Really, they are exactly like flow charts, except that they give instructions in terms of what computers can do vs. what humans can do, and they are usually much larger and more intricate than flow charts you would have seen in school. In fact, in the early days of computer science, before it was even called computer science, there was a confusion about what to call its experts. Some called them flow-charts-men.

So, when we want to tell the computer what to do, we need to speak in a language it can understand and give it instructions which it is capable of following. Using this language and this knowledge, we effectively construct a flow chart which covers situations such as "ask the user his/her age", "do [this] if the user enters 18+ for his age", or "do [this] when the user clicks on this button".

1.2. A quick look ahead

Before we go further, it may help to see an example of what we are talking about, even if you don't understand it yet:

writeOutput("What is your age?"); var userAge = getInput(); if (userAge > 18) { writeOutput("You can see this movie."); if (userAge > 21) { writeOutput("You can also bring alcohol to this movie."); } } else { writeOutput("You cannot see this movie."); }

2. Programming languages

There are very many programming languages, though perhaps only one or two dozen are common enough to be recognizable by any computer scientist. Programming languages may have different purposes or contexts; for example, JavaScript is meant for manipulating elements of web pages and has many built-in facilities for doing that, so, in your instructions to the computer, you can easily enough express "remove this <div>" or "write this pop-up message". Other languages, such as C++ or Java, are considered general-purpose and have very little built-in facilities for any particular environment except black & white "console" input & output (think of DOS). Some languages are built specifically for manipulating advanced math, and some are built specifically to help write artificial intelligence.

Fortunately, most of the common languaes share a very familiar syntax ("C-style syntax") and a similar way of expressing their core components (those which mimic flow charts). So if we learn one of the common languages, we can learn perhaps half a dozen more of them and take advantage of the common language characteristics to help us get started. JavaScript is one of those common, C-style languages, and we will begin to learn programming via its generic features that are not yet concerned with websites.

2.1. Basic input & output

Basically all programming languages have basic, primordial tools with which you can read text input and write text output. In non-Web languages, like C and C++, you might start by writing DOS-like programs, which are keyboard-only. We will use a website environment to replicate this: we will have an area for basic text input and an area for basic text output.

2.2. Language features

This section gives a generic overview of the components of practically any programming language, using JavaScript for example snippets of code.

2.2.1. Variables

A variable is a named container of information. Its motivation is simple: if you want to ask the user for his/her age, or his/her height or weight, you want to store that information somewhere and give it a name so that you can refer to it later. So you might make variables called userAge, userHeight, or userWeight. You can also use variables to contain the results of your own computation. For example, this snippet declares a few variables and does some arithmetic, which we will explore later:

var userAge = getInput(); var currentYear = 2012; var userBirthYear = currentYear - userAge;

2.2.1.1. Naming schemes

You may notice that variables tend to have a distinct naming pattern. There are a few rules which govern the naming of variables, all of which explain what you cannot do. Basically, you cannot begin a variable name with a number; you cannot use a symbol inside the name except for the underscore (_), and you cannot have any spaces inside the name. This is true for nearly all programming languages and you can safely assume these rules when learning a new language.

Beyond that, you can name the variable according to your own styles, though there are a few common choices:

thisIsAVariable
camel case; most common and perhaps most readable
ThisIsAVariable
camel case with uppercase first letter; mixed in the same programs as regular camel case; not as common, meaning most programs seem to have nearly all variable names in regular camel case; sometimes used to distinguish different types of variables (very important?) or, really, as a name for a different kind of programming construct, such as a function name
this_is_a_variable
underscores; still pretty common but less than camel case; was more common in older programs and languages, so it looks a little old nowadays
thisisavariable
all lowercase; difficult to read; rare and almost certainly a poor choice, since better choices are available
THISISAVARIABLE
all uppercase; still somewhat difficult to read; considered poor style because all-caps names are usually reserved for "constants" - containers for information which does not change

2.2.1.2. Declaring variables

Declaring a variable is the act of announcing that the variable exists; "this variable exists as of now". When you declare a variable, you often need some additional syntax to signify the declaration.

In JavaScript, the key word for this is var. You would use var (+ space) before the variable name when you use it for the first time, like this:

var centimetersPerInch = 2.54; var userHeightInInches = 70; var userHeightInCentimeters = userHeightInInches * centimetersPerInch;

Notice that var was only used once per each variable, when they were introduced. In the subsequent uses of those variables, the word var did not precede them.

In actuality, if you omit var in JavaScript, it will still work but may have unintended consequences; make sure you do it. (It makes the variable global.)

2.2.1.3. Data types

In many languages - perhaps most - variables are dedicated to containing specific types of information, such as numbers, text, or structures of other variables (e.g. a series of numbers). These types of information are called data types. You would have to specify in the variable declaration which kind of variable it is. The following example is conceptual and is not valid JavaScript.

text userName = "Bob"; number userBirthYear = 1980; number currentYear = 2012; number userAge = currentYear - userBirthYear;

Some languages have data type declarations like this, and it helps them to maintain correctness (they can warn you if you mess this up) and for faster execution. It does introduce a fairly large amount of complications. Fortunately, in JavaScript, there are no such restrictions, which allows us to learn the language easier. You may put any kind of data in any variable.

Even though you do not need to declare a variable's type.. it is still important to understand the basics of data types, even in JavaScript. This is because each variable still has a type (in a given moment), though it may change, and the type does influence what you can do with the variable and how it behaves. For reference, and for general programming literacy, we'll define the names of most of the basic types; these are universal in programming:

integer
A whole number, like -1, 0, 1, 2, 3, not 2.5 or 3.333 (AKA int, short, long)
decimal
Practically any number, including integers and also 2.5, 3.333, etc. In programming, these are usually called a float or a double. The float name is related to the way the number is stored in the computer - perhaps a dumb name. The double is just twice as big as a float, in a sense (more numbers can be represented) - definitely a dumb name. It is also more common in languages that have both names.
character
One text symbol, such as "A" or "z" or "7" or "@". Some languages distinguish between characters and strings (see below); JavaScript does not. (AKA char)
string
Basically just text. A "string" of characters; zero or more characters. You can define a zero-length string, given as "", which is called the empty string. Strings are enclosed by quotes, and in JavaScript, they can be either single quotes or double quotes ('asdf' or "asdf"). The choice is up to you and it is really motivated by this: whichever one you choose becomes a special character within the string and must be "escaped" (remember &amp; in HTML). For example, "He said, \"Hello\" to me." If you were to use single quotes around it, it would simply be 'He said, "Hello" to me.' Of course, you may run into the same problem with single quotes: 'I say you can\'t just do that.' Pick whichever type of quotes makes easier to write the phrase, and stay consistent in any case.

Data types are perhaps most relevant in JavaScript when considering the text "1234" vs. the number 1234 ("1" + "2" + "3" + "4" vs. one thousand, two hundred and thirty-four). In websites, we often get text input from the user and we typically capture it in text form, even if it would be a valid number. It is usually your job to convert the given text to a number if you know it is appropriate.

In order to convert a textual version of a number to a numeric version, you can call a built-in function (yeah, this presumes that you come back here after reading the section on functions). In order to convert text to an integer, you use the function parseInt(). To convert text to a decimal number (a "float", as described before), use parseFloat(). Actually, these functions will take the first number they see in the text, such as 55 in "55apples". The original text will not change.

var streetAddress = "1938 Asphalt St."; var streetAddressNumber = parseInt(streetAddress); // streetAddress is the same // streetAddressNumber is the number 1938

If you want to read more about these functions, you can read about them on the Mozilla Developer Network: parseInt(), parseFloat()

2.2.1.4. Statements

Statements in programs are like sentences in English. Each statement is a single, compact idea. In the vast majority of programming languages, including JavaScript, a statement is terminated with a semicolon (;). Typically, each statement exists on its own line, though you can feel free to break a statement across several lines if it makes it more readable. As in HTML & CSS, any white space is treated the same as one space. Example:

var padlockNumber1 = 16; var padlockNumber2 = 7; var padlockNumber3 = 5; var padlockFinalNumber = 0 + padlockNumber1 - padlockNumber2 + padlockNumber3;

2.2.1.5. Variable assignment

Perhaps the most common type of statement, and the one we've been using extensively, is the assignment statement; this assigns a value to a variable. In most of our examples, we have been declaring a variable simultaneously, though you don't have to. In this example, we change our mind:

var aNumber = 7; aNumber = 8; aNumber = 9;

The only important note here is that the equals is not quite like the equals you would see in algebra. You are not stating an equality. In fact, to disambiguate this, many languages use a different symbol, such as these:

aNumber := 10; aNumber <- 11;

Now we see an example which clearly demonstrates that we are not stating an equality:

aNumber = aNumber + 1;

Clearly, in algebra, this would be false. What happens here, like in any assignment statement, is that the right half is evaluated first, then that value is stuck into the variable on the left. The left can only have a single variable; i.e. the following is invalid:

aNumber - 1 = aNumber;

2.2.1.6. Operations on variables

When assigning a value to a variable ("setting a variable"), you will probably want to do some arithmetic, such as this:

var heightInCentimeters = heightInInches * 2.54;

This is usually pretty straightforward. Keep in mind that the valid arithmetic symbols in JavaScript (and most common languages) are these: + - * /. There is an order of operations (like PEMDAS), and parentheses come first. This is not just for the four arithmetic symbols seen here but for pretty much any complex expression in programming. You can group stuff in parentheses to establish that the innermost parentheses should be considered first. In fact, this is typically done in arithmetic expressions simply to have a very clear order of operations, so the reader of the code doesn't have to memorize the standard order of operations or make a guess. For example:

whichHorseToWin = ((38 * (5/8)) + 144);

Now for some more formalism. The arithmetic symbols shown before are called operators. There are other kinds of operators, such as && ! =, etc. Basically any symbol you see in a program is an operator. Each piece of data in the expression is called an operand (like 38, 5, 8, and 144 in the example).

The arithmetic operators may also have a different meaning when applied to different data types. The only relevant example in JavaScript is when adding strings. Adding strings together is actually called string concatenation, FYI ("concat the strings"). You use the + operator to add strings, like this:

var greeting = "Hello, " + userName;

You can also make several concatenations in one statement, and this is common. For example:

var message = "Hello, " + userName + ". Your last login was " + lastLoginTimeAgo + " hours ago.";

2.2.1.7. Incrementing & decrementing

Let's go back to our earlier example: aNumber = aNumber + 1;. In this example, we set aNumber to be one more than whatever it already was. This is actually extremely common in programming. It is so common that there is a special syntax for it:

aNumber++;

This statement alone is synonymous to our earlier assignment statement. This is where the language C++ gets its name; it was meant to be like the language C but better. This is also valid:

++aNumber;

These ++ symbols can be called incrementors (actually the "[prefix or postfix] increment operator"). This is because the number is being increased by just one increment (the value 1). These symbols have slightly different behavior than our earlier example of aNumber = aNumber + 1;. In order to stay safe, you can avoid using them in larger expressions such as this:

var anotherNumber = 5 + aNumber++;

What actually happens here is that the previous value of aNumber is used in the computation, and aNumber is incremented later. Weird! If you use the prefix operator - ++aNumber - then aNumber is incremented first and then the new value is used.

There are also decrement operators, such as --aNumber and aNumber--, and they work in complementary ways.

Finally, there are operators which simplify this type of statement in general: aNumber = aNumber + somethingElse;; observe:

aNumber += somethingElse; aNumber -= somethingElse + yetAnotherThing; // subtracts the sum of these two numbers aNumber *= somethingElse; aNumber /= somethingElse;

And yes, the += also works for strings.

2.2.2. Code comments

As we have seen in HTML and CSS, code comments are ways of writing notes-to-self. C-style languages such as JavaScript also have comments, and they all follow the same comment syntax.

There are actually two ways to write comments. In the most common method, you start with two forward slashes, and the comment continues until the end of the line, like this:

// This is a comment // and this is also a comment aNumber = 11;

You can also use a multi-line comment syntax, which begins with /* and ends with */, like this:

/* This is a comment and this is still inside the comment and so is this */ aNumber = 12;

2.2.3. Functions

You can look at functions in a few different ways. If you have a math background, they are procedures which take inputs and produce outputs; in programming, this can also be true. They can also be containers of chunks of code, without taking inputs or outputs. Let's first use them in the mathematical way.

2.2.3.1. Math functions as examples

Consider the math function f(x) = x2. Basically, this takes the given number and produces its square. We can represent this pretty easily in programming:

// This defines the function function SquareSomething(aThing) { return (aThing * aThing); } // This uses the function somewhere else var nine = SquareSomething(3); var threeInAVariable = 3; var alsoNine = SquareSomething(threeInAVariable);

We should be able to deconstruct this example and learn how functions work. So, on the first line, we define a function: we give it a name, and we accept some information in a variable. This variable, aThing, corresponds to x in our math example. Now consider the return statement. The return statement is the statement which declares the result of our function. As you can see, this takes the given number, multiplies it with itself, and uses that as the result of the function. This produced value ("return value") is caught by the code which "calls the function", demonstrated in those last few lines.

2.2.3.2. Function parameters

Parameters are the variables which hold the data given to functions. There may be any number of parameters in a function, not just one. For example:

function Force(mass, acceleration) { return (mass * acceleration); }

Our function is called Force and its parameter names are mass and acceleration. These are now accessible within the function using those names.

2.2.3.3. Arbitrary amount of code within functions; return statement

Using our math example, you may think that functions are limited to quick, one-line expressions, similar to return x2 + 5y + 13;. This is not the case. You can have an arbitrary amount of code inside of a function. Example:

// Counts how many days are in the given range of time function DayCalculator(years, months, days) { var theTotal = 0; theTotal += years * 365.25; theTotal += months * 30; theTotal += days; return theTotal; // You could write some code down here but it would not be reached var somethingElse = 7; }

You can do anything you want inside of a function. They can be much longer and much more complicated than this, and they often are. When you finally use return, it will end the function and give the value following "return" to the function caller. If there is any code after a return statement (at least in our examples so far), it will not be reached.

2.2.3.4. Scope of parameters & variables

In programming, the scope of a variable is the region of code in which the variable is valid. Outside of that scope, the variable is not defined and has no meaning. For example, consider these two functions:

function FunctionA(valueX) { var userHeight = 70; } function FunctionB(valueY) { var userWeight = 170; }

No information is shared between these two functions. The variable userHeight is not usable in FunctionB, and likewise, userWeight is not usable in FunctionA. They could actually both have variables called userHeight and userWeight, and there would be no conflict or sharing of information. They would simply be oblivious to each other.

So what is the scope of a function parameter? A function parameter works exactly like a variable that is declared within a function, including scope.

2.2.3.5. No parameters

It is possible and often useful to have a function which does not take parameters. This is where we may diverge a little from the concept of a function in pure mathematics. Sometimes, functions like this tell us something about the environment, and we call the functions in order to check on those environmental conditions. Examples:

// "The system" (system which runs your JavaScript code) may define a function like this. // Its "[function] body" (lines inside braces) would be a lot more complex than this. function CurrentTime() { // return '2:24 PM'; // perhaps something like this } function GetUserInput() { // return whateverTheUserSaid; // something }

We don't really need to give any parameters in these cases; we are simply retrieving or consuming information. In real life for these cases in particular, specifically with CurrentTime, we may actually give some parameters that specify how we want to format the time (like whether to use 12-hour or 24-hour notation).

2.2.3.6. No return

In an even farther departure from math: you don't even have to return a value inside of a function. Some languages make a distinction in this case and call these functions procedures; most languages don't. Example:

function ShowTheUserAMessage(theMessage) { // alert(theMessage); // ^^ a feature of JavaScript }

2.2.3.7. As bags of code

So we don't need to take parameters, and we don't even need to return anything. We can just have a function with some lines of code inside, and that's it. In fact, this is pretty common, although functions usually take parameters. And there are actually benefits to making functions simply to contain, or "encapsulate", a chunk of code. The benefits are more in the realm of software design and how you choose to organize the structure of your program. For example, let's see the benefit of encapsulation:

// This is the function which has the relevant "encapsulated" logic. function BodyMassIndex(weightInPounds, heightInInches) { return (weightInPounds * 703) / (heightInInches * heightInInches); } function GiveUserHisOrHerBMI(userName, userWeight, userHeight, userHairColor) { // Call the function and store its result. var theBMI = BodyMassIndex(userWeight, userHeight); // Show the user his/her BMI. // We'll break up the creation of the string across multiple lines, // so it is more easily readable. ShowTheUserAMessage("Hey, " + userName + ", who has " + userHairColor + " hair. Your BMI is " + theBMI); } function CalculateBMIsInDatabase() { // woop woop a database // look at all the records in the database which have people, // their weight, height, etc. // now calculate their BMIs and store them alongside the weights and // heights. var thisGuysBMI = BodyMassIndex(weightOnRecord, heightOnRecord); // ... }

The logic for computing BMI is only written in one place, which is more convenient than writing it out in each place, in terms of whatever variable names you have in each place (notice userWeight, weightOnRecord). It is also much easier to guarantee that the BMI calculation is correct if it is only written once; imagine if one of 100 occurrences of BMI calculation were incorrect, because you copied & pasted the BMI logic throughout your program and slightly adapted it each time. Function encapsulation is a tremendous benefit, and any time you see a problem that can be solved generically and then reused in multiple places, you should probably make it its own function.

2.2.4. If-statements

Up to this point, we have had no variability in the logical path we take within each function. The data values may change, because they are in variables, after all, and variables can vary. But the steps that we take have not varied depending on the given information. We said that programs are like flow charts, after all, and flow charts represent different logical steps that you can take; e.g. "if the glass is not full yet, keep pouring; else stop pouring". There are programming structures we can use to capture this kind of variability, most notably the if-statement. Example:

function TellUserIfCanSeeMovie(userAge) { if (userAge > 18) { ShowTheUserAMessage("You can see the movie."); } if (userAge < 18) { ShowTheUserAMessage("You cannot see the movie."); } }

This logic is actually a little incorrect, but it's a good basis for now.

So this is an if-statement. It's pretty simple. The expression inside the parenthesis has to have a value of true or false, so it cannot be something like x + 7 (even if it could, depending on the programming language, you probably shouldn't do it).

2.2.4.1. Comparison operators

When you make a comparison for the expression within the parenthesis, such as our userAge > 18, you can use some new operators (remember arithmetic operators from before: symbols such as +, +=, etc). These are generally called logical operators or sometimes comparison operators.

A few of them are intuitive: < and > work pretty much exactly as you would expect (however, see next section). Some of them are not the syntax you would guess.

If you want to test for equality, you need to use a double equals sign, such as ==. If you use a single equals, it will try variable assignment. This is the case for most popular languages and is generally considered a regrettable design decision. You just have to know about it step around it.

If you want to test for a numeric range, such as userAge ≥ 21 (greater than or equal to), you will have to use a combination of symbols: >=. Similarly, there is <=.

If you want to negate an expression, you have a couple options. If you simply want to test whether a value is not equal to another, you can use !=, such as userAge != 8. Alternatively, you could surround the expression in parentheses and put a ! before it, such as !(userAge == 8) or !(userAge >= 21).

2.2.4.2. Comparison & data types

Comparisons have different meaning depending on the data type. If the data is an integer, such as userAge, checking if userAge > 18 will only become true at ages 19 and over. When conceptually we mean 18, such as 18 and 1 day, 18 and 3 months, etc., for integers, the next step is simply 19. So you probably mean userAge >= 18 or perhaps even userAge > 17.

You can also compare string data. If you say player1Name < player2Name, for example, this could make sense. This is comparing using an order that is approximately alphabetic (actually "lexicographical"; includes numbers and symbols in a certain order (can usually assume ASCII)).

So this is another example where you must know the data type if you want to write an intelligent comparison, regardless of the fact that JavaScript lets you stick anything you want in a variable using var.

2.2.4.3. Boolean data type

There is actually another data type: the boolean type. One of these could also be called a "bool"; this is most common. This type of variable can hold the values true or false. Example:

var thisIsABool = true; var another = false;

We can also use expressions that evaluate to true or false. Example:

var userIsOfLegalAge = (userAge >= 18);

Since we can do that, we can actually use boolean variables directly in if-statement expressions:

if (userIsOfLegalAge) { // ... }

This is similar to saying "userIsOfLegalAge == true", but that is actually redundant, so we can just do this. Likewise, you can say if (!userIsOfLegalAge).

2.2.4.4. Compound expressions, parentheses, and order of operations

If-statements can be far more complex than those we've seen. The structure is the same, but the boolean expression inside the parentheses may be much more complicated, like any math expression with several variables and operators.

You can say something like "if user age is greater than 18 and less than 25, [do this]". Let's see that example:

if ((userAge >= 18) && (userAge <= 25)) { // do this }

You can group simple true/false expressions in parentheses and then combine them. When you combine them, you can can use operators which effectively mean and/or. The and operator might literally be "and" in some languages, but it is usually a double ampersand: &&. Similarly, you could type "or" in some languages, but you most commonly use a double bar: || (typically shift + backslash). Example of an or expression:

if ((userName == "Paul") || (userName == "Ringo")) { // let him in }

Notice that this would not work with and, because a user's name cannot be two things at the same time. This is a common rookie mistake.

The and/or operators probably work how you would expect, but if you would like a formal introduction, look up "boolean logic" or "boolean algebra"; see Wikipedia.

As you can see, when you have multiple expressions, you can group them with parentheses. You can have sub-expressions and sub-sub-expressions if you want; there is no limit. Just keep stacking up the parentheses. If you don't use parentheses for expressions, you rely on the order of operations (remember PEMDAS). This is language-specific but you can generally assume it's the same across languages. However.. you probably should not rely on the order of operations. You should use parentheses to remove all ambiguity and separate your code cleanly so that it is readable, especially to other people. Omitting parentheses is generally considered annoying, perhaps offensive, and a give-away trait of the inexperienced.

2.2.4.5. else

You can also do this:

if (userAge >= 18) { ShowTheUserAMessage("You can see the movie."); } else { ShowTheUserAMessage("You cannot see the movie."); }

This is considered cleaner than our first example.

2.2.4.6. else if

Similar to the if-else construct in the previous section, you can chain multiple conditions together, like this:

if (userAge >= 18) { ShowTheUserAMessage("You can see the movie."); } else if (userAge >= 13) { ShowTheUserAMessage("You can at least see PG-13 movies."); } else if (userAge >= 5) { ShowTheUserAMessage("You can at least see G movies (assuming the cutoff is 5)."); } else { ShowTheUserAMessage("You practically can't see any movies."); }

2.2.4.7. "Nested" if

The if-statement structure, includig all forms of it, with else and else if, can be "nested" within another if-staetment. There is no limit to how deep your structure can go, and it is typical to see two- or three-deep structures. Example:

if (userAge >= 18) { ShowTheUserAMessage("You can see the slasher movie."); } else if (userAge >= 13) { if (parentIsPresent) { ShowTheUserAMessage("You can see the slasher movie because your parent is present."); } else { ShowTheUserAMessage("You cannot see the slasher movie."); } }

2.2.5. while loops

We are still missing one final piece of the majestic flow chart: repetition. You have probably seen flow charts which have a circular flow in them, such as "invite people in the room; if the room is not full yet, repeat". We must have an equivalent structure in programming in order to make useful and convenient programs. Enter the while loop.

The while loop is a structure which encloses an arbitrary section of code that executes repeatedly. Conceptual example:

var someCondition = true; var moneyInTheBank = 8.79; while (someCondition) { moneyInTheBank += 1; moneyInTheBank *= 1.005; }

As long as someCondition is true, those two lines will repeat. In this example, however, someCondition never changes, so we actually loop forever. This is practically never desirable, so we usually structure the loop so that the inside of the loop changes the loop condition, eventually breaking it.

2.2.5.1. Counting loops

A typical example for looping is to loop a certain number of times; say that you want to execute a given piece of code five times. You might do it like this:

var loopCounter = 1; var moneyInTheBank = 8.79; while (loopCounter <= 5) { moneyInTheBank += 1; moneyInTheBank *= 1.005; loopCounter++; }

Step through the code in your head. The variable loopCounter is incemented each time, and it eventually becomes 6, which, when put into loopCounter <= 5, makes the expression false. At that point, the code inside the loop is not executed.

So this may be seen as a generalization of most while loops:

while (someCondition) // maybe not even a variable, just an expression { // do something // affect someCondition }

2.2.5.2. do..while loops

What happens when the condition is false the first time? The code is not executed. For example, the code inside this loop never runs:

var loopCounter = 88; while (loopCounter <= 5) { // do something loopCounter++; }

What if you want it to run at least once? This is sometimes useful. There is a variant form called a do..while loop which does this. Example:

do { // something } while (someCondition);

Notice the semicolon at the end. So, this "something" code executes at least once, regardless of whether someCondition is ever true.

2.2.5.3. break and continue

There are two simple statements, break and continue, which have special meaning in relation to loops. You may use them like this:

while (someCondition) { // maybe do a little work if (shouldSkipThisTime) { continue; } // do some more work if (allLoopWorkIsDone) { break; } }

If you use continue, it skips the rest of the loop iteration (i.e. does not "do some more work" in the above example) and starts a new loop iteration. If you use break, it stops looping immediately.

do { // something } while (someCondition);

Notice the semicolon at the end. So, this "something" code executes at least once, regardless of whether someCondition is ever true.

2.2.6. for loops

Not all loops are counting loops, but counting loops are probably the most common. So there is another kind of loop which is basically a rephrasing of the while loop that makes counting easier; it is the for loop. Example:

for (var someCounter = 1; someCounter <= 5; someCounter++) { // do whatever // may also reference someCounter in here; its value changes every time }

The for loop has four sections. Let's notate them generally and describe them.

for (A; B; C) { D }

They are as follows:

A
Executes before the loop begins
B
Checked before every loop iteration, like a while loop (not a do..while)
C
Done after every loop iteration (after D, before A)
D
Any sequence of statements; done for each loop iteration, as long as B is true

In 95% of cases, for loops look almost exactly like our first example. There are two typical differences and they are cosmetic. This is an exactly typical example:

for (var i = 0; i < someLimit; i++) { // do whatever }

The loop variable, or loop iterator, is usually called i. This is for a historical reason. The second difference is that the counter usually starts at zero; this necessitates that the condition become less-than in order to count the same number of times. This is just a very pervasive convention, though it comes in handy later (because it fits with other arbitrary conventions).

The statements break and continue are valid inside of for loops, as well.

A final note on loops.. You should probably not mess with the loop variable inside of the loop. Only read from it, do not modify it, unless you are both an expert and an awful person.

2.2.6.1. Nested loops

Like nested if-statements, you can also nest loops. You can nest any kind of loop — while, do..while, or for (you can nest practically any kind of structure within another, except for a function (in most languages)). For example,

for (var i = 0; i < someLimit; i++) { // do whatever for (var j = 0; j < anotherLimit; j++) { // do another kind of whatever } // still do whatever }

As you might expect, the entire j loop executes for every iteration of the i loop.

The names of nested loop variales typically continue as j and k. Nested loops are somewhat uncommon and three-nested loops are rare.

2.2.6.2. Comparison of loop types

If you have a for loop, why use a while loop? Well, for loops are fairly ideal for counting, and while loops are typically used for other situations.

There are perhaps two typical uses of while loops. In one case, you may just want to loop until a given computation is complete (passes a threshold), because it would be infeasible to calculate the number of iterations in advance and make it a for loop. For example:

var howManyMonthsDidItTake = 0; var moneyInTheBank = 8.79; while (moneyInTheBank <= 1000000) { moneyInTheBank += 10; moneyInTheBank *= 1.005; howManyMonthsDidItTake++; }

In that case, you could deposit $10 every month, with 0.5% monthly interest, and the loop continues until you have a million dollars. To be extra useful, it computes how long it took to reach a million dollars.

In the second use case, you may loop an indeterminate number of times. This is often when you're asking for user input and the user keeps giving you incorrect input. There's no telling how many times that will take. If you ask for the user's age and he keeps giving you a string ("asdf"), it could go on forever. So a loop might look something like this:

var userInputIsValid = false; do { ShowTheUserAMessage("Enter your age."); var userInput = getUserInput(); // made-up function name; assume this exists if (userInput is a number) // pseudocode; this will be different in each language { userInputIsValid = true; } } while(!userInputIsValid);

You could also use a break to spice things up. For example:

do { ShowTheUserAMessage("Enter your age."); var userInput = getUserInput(); // made-up function name; assume this exists if (userInput is a number) // pseudocode; this will be different in each language { break; } } while(true);

2.2.7. switch statements

This final structure is in most programming languages, though it is not extremely common in programs. It is a simplification of this type of construct:

var userMoney = 0; if (userName == "Paul") { userMoney = 100; } else if (userName == "John") { userMoney = 95; } else if (userName == "George") { userMoney = 50; } else if (userName == "Ringo") { userMoney = 20; }

If you simply have a bunch of equality checks on the same variable, you can structure them in a switch statement like this:

var userMoney = 0; switch (userName) { case "Paul": userMoney = 100; break; case "John": userMoney = 95; break; case "George": userMoney = 50; break; case "Ringo": userMoney = 20; break; // The "default" case executes if none of the others fit default: userMoney = 1; break; }

That's pretty much it; copy this example if you want to use it. It's just a more readable and perhaps more convenient syntax. You can have any number of statements in each case, before the break statement.

3. Getting started with JavaScript

So, how do you get started? JavaScript is a fine enough language to use for an introduction to programming, because it shares a style of syntax ("C-style syntax") with most common languages and because all you need to get started are a web browser and a text editor. All of the examples in this document are JavaScript, though some of them use made-up function names.

You can get started on your own custom web page, a web page provided alongside this document, or a popular online testing environment.

3.1. The <script> tag

You need to refer to JavaScript from within an HTML document, similar to how you do for CSS. You can encompass lines of JavaScript in their own tag or you can refer to an external JavaScript file. Both of these are actually accomplished with the <script> tag. Unlike the <style> tag for CSS, the <script> tag can go anywhere in the document.

To encompass lines of JavaScript, do as follows:

// some HTML.. <script type="text/javascript"> var someVariable = 7; var anotherVariable = someVariable + 9; </script> // more HTML..

You don't need to indent your code like that, but it would be nice. You also don't need the attribute type="text/javascript" with HTML5, but you might as well keep it there for backwards-compatibility.

To refer to an external file, use the tag with a src attribute and with no body:

// some HTML.. <script type="text/javascript" src="path/to/aJavaScriptFile.js"></script> // more HTML..

This functions exactly like the JavaScript code were pasted inside the script tag, like our first example.

One interesting note is that all JavaScript code snippets included within an HTML file share the same functions and variable names, so you could define a function in one <script> tag and use it in another.

3.2. The JavaScript console, document.write and alert

These are your most basic methods of output and debugging. With these, you can basically dump some text to the screen in one way or another.

The JavaScript console is a text-output area within the web browser which is normally hidden. You can typically find it in some kind of "Web Tools" or "Developer Tools" menu of the browser program, and you can often get there by pressing F12. The console will show you errors, so you should check it in case something just doesn't appear to be working. You can also write to the console. You can call the built-in function console.log and you can give it a string, a number, an object (see later), or pretty much anything. Example:

console.log(myVariable);

If you are using Firebug, it has its own version of the console which has some extra convenience. If you are dumping arrays or objects to the console, it will give you a visual representation, which is extremely helpful.

You may also call the built-in function document.write, and this will write HTML to the page. It is rare to see this in any real site (there are more professional alternatives), so you should only use this while debugging or playing around. Example:

// some HTML.. <script type="text/javascript"> document.write("<p>Hey, my variable is " + myVariable + ".</p>"); </script> // more HTML..

Finally, you can launch a pop-up message by calling the built-in function alert. This is also known as window.alert; they are two names for the same function. Try it:

alert("Hey.");

3.3. The Programmin' Playground

This is bundled with the course materials

The Programmin' Playground is a simple website environment for giving the user a text prompt, accepting text input, and writing text output, all of which are managed by functions defined in its helpfulFunctions.js file. Using these functions, you can choose not to worry about the website-specific details of JavaScript or even many of JavaScript's built-in functions (like document.write or alert). So this may be a good introduction to programming in general, not just web programming. Launch the playground page and read its instructions to begin.

3.4. jsFiddle

The site jsFiddle.net is a site for quickly playing around with HTML, CSS, and JavaScript. You can develop a snippet of code (of all three languages) and generate a link so you can send it to someone else. This has become pretty popular and pretty helpful in the programming community.

3.5. JSLint

There is not exactly an official validator for JavaScript code like there are for HTML and CSS. However, this one unofficial guy, Dogulas Crockford, is a JavaScript expert and has written his own validator. The validator also gives some suggestions on correcting poor style and avoiding pitfalls. Its website is JSLint.com.

3.6. Google & Stack Overflow

Many programmers have come before you. You can almost always find the answer to an introductory programming question with a little Googling; be sure to mention which programming language you're using in order to get more relevant results. The site Stack Overflow is specifically designed as a site for programming questions & answers, including many newbie questions. Your question has probably already been asked by somebody else, so try to find that before asking a duplicate question.

4. Common programming patterns

Now you know the basic building blocks of most programming languages. People have grown to use these tools in typical ways; here are some of them.

4.1. Boolean "flags"

You know that boolean variables can store true or false. You can use these in some helpful ways.

4.1.1. For later or repeated if-statements

You've seen that you can use a boolean variable in an if-statement; here are some refresher examples:

var aBoolean = true; if (aBoolean) { // do something } if (aBoolean && (userAge > 18)) { // do something }

You may want to leverage this to simplify your if-statements and especially to save a true/false value for a later if-statement or a repeated one. First, for simplifying if-statements:

var userIsInTargetDemographic = (userAge >= 18) && (userAge <= 25) && (userGender == 'M'); if (userIsInTargetDemographic) { // do something }

By giving a name to the expression, you can make the if-statement more readable. You could also have done that with a comment:

// Check if the user is in the target demographic if (userAge >= 18) && (userAge <= 25) && (userGender == 'M') { // do something }

So that is more of your choice, one way or the other (but please do one of them). Code readability is an excellent goal in programming and it is one that is only recently becoming appropriately emphasized.

Aside from readability, is it ever useful to save an expression like that in a boolean? Yes. Here is one typical example:

var userIsInTargetDemographic = (userAge >= 18) && (userAge <= 25) && (userGender == 'M'); // Get some user input writeSomeOutput("What is your favorite movie?"); var someInput = getSomeInput(); // If appropriate, save some statistics if (userIsInTargetDemographic) { saveFavoriteMovie(someInput); } // Get some user input writeSomeOutput("What is your favorite TV show?"); var someInput = getSomeInput(); // If appropriate, save some statistics if (userIsInTargetDemographic) { saveFavoriteTVShow(someInput); }

In this example, you could have written the userAge and userGender expression each time, but this example is more readable, easier to verify, and easier to maintain. Copied & pasted code is one of the main sources of errors; you might forget to change one little part after pasting, or you may forget to update all of the copied & pasted occurrences of the expression if you want to change it. With setting one boolean variable, you can change the meaning of that variable in one step (add some criteria about the person's income?) and it is effectively updated everywhere.

4.1.2. As function parameters

Function parameters will often be a boolaen type. It's an easy way to express a preference; it's like asking "Yes"/"No". For example:

function ComputeCompoundInterest(principal, apr, years, shouldRoundOff) { var runningTotal = principal; // Apply the APR for the given number of years for (var i = 0; i < years; i++) { runningTotal *= 1 + (apr / 100); } // If desired, round off the number to two decimal places if (shouldRoundOff) { runningTotal = Math.round(runningTotal, 2); } // Return the total return runningTotal; }

4.2. Global variables

We have seen so far that you can have variable within a function and it is valid only for its function. That is the variable's scope. Now we will see that you can also have variables outside of functions. Those variables are valid everywhere and thus they are called global variables. The regular variables you've seen before are called local variables. Example:

var userName = "(none)"; var userAge = 0; function FunctionA() { var someBMI = 25; // etc. etc. writeSomeOutput("Hey, " + userName + ", your BMI is " + someBMI); writeSomeOutput("And your age is " + userAge); } function FunctionB() { writeSomeOutput("What is your age?"); userAge = getSomeInput(); }

The variables userName and userAge are accessible everywhere in the program, and they may also be modified from everyhwere in the program.

4.2.1. Temporal relationships; order of execution

So, in our earlier example, FunctionA() reads from the userName and userAge variables, and FunctionB() writes to userAge. (Perhaps elsewhere, userName is defined.) So does FunctionA() read the changes made by FunctionB()? Well, it depends. It depends on the order in which they were called. If FunctionB(), the producer, is called before FunctionA(), the consumer, then yes; else FunctionA() will see the original values for those variables.

Complications like these make global variables somewhat more dangerous than local variables, and many or most professional programmers try to avoid global variables as much as possible due to reasons like this, especially within the context of an already-complex program (global variables are probably fine for your small, educational programs). A way to avoid global variables in general is to pass the information with all the function calls instead.

4.2.2. Code in global scope

Actually, you can have any code in global scope, not just variable declarations. You can do computation, ask the user for input, write output, etc. And after all, how do you think these functions are called? Example:

var userName = "blah"; function AFunction() { // ... BFunction(); // ... } function BFunction() { // ... } // Get some user input writeSomeOutput("What is your name?"); userName = getSomeInput(); // Now call a function and get the ball rolling AFunction();

4.2.3. Using them as semaphores

For better or worse, we have an easy way to persist some information between function calls. This can allow us to have an arrangement like this:

var stage = 1; // 1: start/get name // 2: get height // 3: get weight // 4: done var userName = ""; var userHeight = 0; var userWeight = 0; function PromptTheUser() { if (stage == 1) { writeSomeOutput("Please enter your name."); } else if (stage == 2) { writeSomeOutput("Please enter your height in inches."); } else if (stage == 3) { writeSomeOutput("Please enter your weight in pounds."); } } function ProcessSomeInput() { var theInput = getSomeInput(); if (stage == 1) { // Is the name valid? sure. userName = theInput; stage++; } else if (stage == 2) { // Is the height valid? if (theInput > 0) { userHeight = theInput; stage++; } else { writeSomeOutput("The given value must be positive."); } } else if (stage == 3) { // Is the weight valid? if (theInput > 0) { userWeight = theInput; // Finally, compute the BMI and output it. var theBMI = BMI(userHeight, userWeight); writeSomeOutput("Hey your BMI is " + theBMI); stage++; } else { writeSomeOutput("The given value must be positive."); } } } while (stage < 4) { PromptTheUser(); ProcessSomeInput(); }

In this example, the global variable stage is a way of changing (modulating, if you will) the behavior of these functions. This example is a little bit contrived; event-driven programming in JavaScript is actually a better fit for this. But at least you can see how this is possible. Since this uses global information, this is another design that would usually be discouraged for large, complex, or professional programs, but it is good to know.

The title of this section refers to train-track semaphores

4.2.4. Conflicting local variables

What if you name a local variable the same thing as a global variable? Well, in most languages, you can do that. And then you would begin using the local one; the global one would probably become inaccessible from within that function. It depends if the language gives you a way to refer to the global one explicitly (something conceptually like global.userName). In any case, whether you can do it or not, you probably shouldn't. It would be considered poor style, since this makes the program less readable and less clear; it also increases the general risk of screwing something up.

5. JavaScript's features

So far, this information has been applicable to the vast majority of programming languages. This is where we diverge just a little bit and talk about some of JavaScript's features in particular.

5.1. The null value

In JavaScript, as in many or most languages, variables can have the value null. For example, you can do var myVariable = null;. This may be a way of declaring the variable but not wanting to give it a particular value yet (you could also just do var myVariable;). The value null means "unknown" or "undefined". Sometimes it will act as the number 0 if you use it as an integer (e.g. var theSum = 5 + 3 + null;). If you use it as a string, it would act like the empty string (var theString = "Hey, " + null;).

5.2. String functions

Strings in JavaScript have bulit-in functions that can tell you more about the string or let you do string manipulations. The first example is actually not a function but is like a sub-variable that the string has:

var aString = "Hey, John."; var howLongIsIt = aString.length; // produces the number 10

The rest of them are actually functions, such as this:

var aString = "Hey, John."; var uppercaseVersion = aString.toUpperCase(); // "HEY, JOHN.";

There are also functions for searching within the string:

var aString = "Hey, John."; var whereIsTheComma = aString.indexOf(","); var whereIsJohn = aString.indexOf("John");

An important note here is that the numbers start counting at zero. The "H" is at index zero.

There are several more functions, and you can find references online, such as W3Schools; the functions are called "methods" if they stem from a variable such as the string. The one important thing to remember about these string functions is that they do not modify the original string. Note how we had to make a copy of the string to capture the uppercase version. If you actually want to convert the string to uppercase, you must do something like this:

var aString = "Hey, John."; aString = aString.toUpperCase(); // overwrites itself

5.3. Arrays

Arrays are collections of variables. More specifically, an array is a numbered sequence of variables, such as this:

var listOfGrades = aMystery; // go with it for now var gradeTotal = 0; // Add the first, second, and third grades to the sum gradeTotal += listOfGrades[0]; gradeTotal += listOfGrades[1]; gradeTotal += listOfGrades[2];

You actually create arrays like this:

// Creates an empty array; can add items later var arrayOne = []; // Variant of #1, rarely used, because it is needlessly verbose var arrayTwo = new Array(); // Creates an array with five items var arrayThree = [33, 44, 12, 8, 177]; // Use the above array: var itemOne = arrayThree[0]; var itemTwo = arrayThree[1]; var itemThree = arrayThree[2]; // etc..

5.3.1. Reference semantics

If you refer to the variable as arrayThree[someNumber], even if someNumber is a variable, it refers to that item in the list, at position (someNumber + 1), in terms of natural numbers and counting. If you refer to the variable without the brackets, such as just arrayThree, you refer to the whole array. You can make two variables refer to the same array in this way:

var anotherVariable = arrayThree;

In this case, actually, these two variables now refer to the same array. So you would have to think about this kind of thing:

var anotherVariable = arrayThree; arrayThree[2] = 180; // anotherVariable[2] is now also 180

This kind of behavior is generally called reference semantics; i.e. the variables in this case refer to the same piece of information. This has not been true of any variables we've seen before, but we will see this again. (Actually, it's true of strings, but it has no effect except for using computing resources more efficiently.)

5.3.2. Array functions

Just like with strings, JavaScript gives you a set of functions stemming from each array. The first one, again, is length, which is not exactly a function:

var anArray = [1234, 23, 111]; var itsLength = anArray.length; // the number 3

And just like before, you can find a reference on W3Schools. There are five functions which are particularly useful:

push()
Adds an element to the end of an array
pop()
Removes an element from the end of an array
shift()
Removes an element from the beginning of an array (removes [0]; the old [1] becomes the new [0])
unshift()
Adds an element to the beginning of an array (becomes the new [0])
join()
Creates a string with all of the array values in it, with a given string delimiter appearing between each array element (like a piece of glue); try aString = anArray.join(", ");

5.3.3. Arrays and for loops

Arrays and for loops are fast friends. Using a for loop, you can step over all of the elements of an array and then perhaps dump them out or manipulate them all:

var anArray = [1234, 23, 111]; // Dump out all the elements for (var i = 0; i < anArray.length; i++) { writeSomeOutput("The value at " + i + " is currently " + anArray[i]); } // Modify each element; multiply each of them by 10 for (var i = 0; i < anArray.length; i++) { anArray[i] *= 10; }

5.4. Objects

Like arrays, objects are collections of variables, except they are not organized in a list. They are just in a bag, and each sub-variable has its own name. For example:

var objectOne = {}; // equivalent of #1, basically never used, like "new Array()" var objectTwo = new Object(); var objectThree = {}; objectThree.favoriteColor = "red"; objectThree.favoriteShape = "square"; objectThree.numberOfThings = 37; // access the object var getSome = objectThree.favoriteShape;

Similar to arrays, you can also define an object and give it some values in the same line of code:

var favoriteThings = {color: "red", shape: "square", aNumber: 37}; var moreSpacedOutSyntax = { color: "red", shape: "square", aNumber: 37, };

These sub-variables, such as "aNumber" and "favoriteShape", are actually called properties, or fields, rather than sub-variables.

5.4.1. Passing objects around; reference semantics

Just like arrays, objects have reference semantics, meaning that if you set one variable equal to another variable which is an object, they both actually point to the same data. And like arrays, it is often useful to pass around the entire object:

function PrintFavoriteThings(someFavorites) { writeSomeOutput("Fav. color? " + someFavorites.color); writeSomeOutput("Fav. shape? " + someFavorites.shape); writeSomeOutput("A number? " + someFavorites.aNumber); } var favoriteThings = {color: "red", shape: "square", aNumber: 37}; PrintFavorieThings(favoriteThings);

5.4.2. Ways of accessing properties

As we've seen so far, you can access an object's properties like this:

var objectThree = {}; objectThree.favoriteColor = "red"; objectThree.favoriteShape = "square"; objectThree.numberOfThings = 37; // access the object var getSome = objectThree.favoriteShape;

But you can also access them like this:

var objectThree = {}; objectThree.favoriteColor = "red"; objectThree.favoriteShape = "square"; objectThree.numberOfThings = 37; objectThree.favoriteBMI = 26.1; // access the object var getSome = objectThree["favoriteShape"]; var getSomeMore = objectThree["favoriteColor"]; var getEvenMore = objectThree["number" + "of" + "things"]; var aPropertyName = "favoriteBMI"; var getBMI = objectThree[aPropertyName];

Notice that we're using quotes here and we're actually buliding strings that will be used as property names. And wherever we have a string, we can also use a variable. This can allow for some cool things.

5.4.3. A special kind of for loop

This is a type of loop which uses the word for but is unlike our traditional for loop; its syntax is also practically unique to JavaScript. This for loop lets you iterate over the properties in an object:

var objectThree = {}; objectThree.favoriteColor = "red"; objectThree.favoriteShape = "square"; objectThree.numberOfThings = 37; objectThree.favoriteBMI = 26.1; for (var thisIsAPropertyName in objectThree) { writeSomeOutput("Value of ." + thisIsAPropertyName + ":"); writeSomeOutput(objectThree[thisIsAPropertyName]); }

In the examples so far, we needed to know the property names in advance, but now we don't need them if we are doing batch operations on the object.

5.4.4. Nesting & composition

An object can hold anything - including an array or even another object. (An array can also hold anything, by the way.) So you may end up with an object which is actually a multi-layer structure of information, such as this:

var peopleInTheRoom = { Adam: { height: 68, weight: 160, favoriteFood: "steak" }, Bob: { favoriteColor: "blue" }, Carol: { favoriteColor: "red", kids: { David: { favoriteThing: "dinosaurs" }, Eddie: { brokeTheVase: true, actionFigures: ["Buzz", "Woody", "something"] } } } };

Because of this, objects might be helpful ways to store natural phenomenon or structural information.

5.4.5. JSON

JSON stands for JavaScript Object Notation. It is the syntax of the way we notate objects in JavaScript, such as in the above examples. Because it is relatively easy to describe objects in JavaScript, JSON is actually a popular format, like a file format, used in many kinds of programs — even ones which are not written in JavaScript. It is particularly popular on the web and has seemingly overtaken XML as a format for describing any kind of structured information. See more on Wikipedia.

JSON is actually slightly more strict than actual JavaScript, most notably in that the property names have to be quoted, like this, and you are allowed to have a comma after every item, even the last one:

var peopleInTheRoom = { "Adam": { "height": 68, "weight": 160, "favoriteFood": "steak" }, "Bob": { "favoriteColor": "blue" }, };

5.5. Variadic functions

Variadic functions are functions which may take any number of parameters; e.g you could call myFunc(123), myFunc(123, 456, 789), or myFunc(). In JavaScript, all functions are actually variadic. You won't see an error if you fail to give values for all the declared parameters (a language feature that programmers would consider sloppy and unhelpful). And you can capture any number of parameters that are given to you.

This topic is one of the most advanced in this document, and it is not necessary for everyone to learn how to define variadic functions in JavaScript, but you should at least read it if you're curious.

5.5.1. Defining variadic functions

Using a variadic function is easy, though defining a variadic function takes some work.

5.5.1.1. The arguments array

In every function, the variable arguments is automatically defined. This is the array of values given for the function parameters.

Sidetrack in programming-language terminology: the list of function parameters' variables and their names is actually the list of parameters. The list of values given when the function is called is the list of arguments. For example:

// Declaration: function DoSomething(name, age, height) { // ... } // Use: DoSomething("John", 18, 68);

In this snippet, name, age, and height are the parameters, and "John", 18, and 68 are the arguments.

So, there's an arguments array. That means you can do this:

function DoSomething(name, age, height) { var theFourthArgument = arguments[3]; // gets "extraThing" as given below var theFifthArgument = arguments[4]; // gets 789 var theFirstArgument = arguments[0]; // same as name! } DoSomething("Adam", 18, 68, "extraThing", 789);

5.5.1.2. Accepting extra arguments

The most basic use of variadic functions is declaring very few parameters (or no parameters) and accepting more arguments than the number of parameters you have declared. To do this, you just use the arguments array, really. This section will have examples of some useful special cases, though.

In this first example, we declare no parameters:

// Finds the maximum value within the given values function FindTheMax() { // Start with a value that will be overwritten var currentMax = null; // Iterate through the arguments for (var i = 0; i < arguments.length; i++) { var currentArgument = arguments[i]; // Check if this argument should be the new max if (currentArgument > currentMax) { currentMax = currentArgument; } } // Return the max found return currentMax; } var theMax = FindTheMax(5, 77, 81, 33, -14, 9); // returns 81

In this second example, we declare some parameters and leave the rest to be variadic:

// Combines the extra arguments into a string function ProduceStringFromList(delimiter, shouldCapitalize) { // Keep a cumulative string var cumulativeString = ""; // Iterate through the arguments after the first two given for (var i = 2; i < arguments.length; i++) { // This is just for convenience/clarity, of course var currentArgument = arguments[i]; // Add the argument and also the separator/glue string. // Note that the last one will have the glue at the end.. a rookie // mistake, though fixing it would needlessly complicate the example. cumulativeString += currentArgument + delimiter; } // If desired, capitalize the whole thing. if (shouldCapitalize) { cumulativeString = cumulativeString.toUpperCase(); } // Return the cumulative string return cumulativeString; } var theString = ProduceStringFromList("::", true, "hey", "you", "asdf" 555); // theString is now "HEY::YOU::ASDF::555::"

5.5.1.3. Ignoring omitted arguments

A more difficult problem is when you want to make some parameters optional. For example, you want to make a function like this:

function BMICalculator(height, weight, shouldRound, roundToDecimalPlace) { // ... } var theBMI = BMICalculator(68, 170); // assuming shouldRound => true and roundToDecimalPlace => 2

You would like to make some of those parameters optional. How do you do it? There are a few different ways to do this, but let's see one example. You can pretty much just copy this pattern; hopefully you also take a good look at it and it makes sense to you:

// In this function, aaa, bbb, ccc, and ddd are meant to be optional function HasExtraParameters(thingOne, thingTwo, thingThree, aaa, bbb, ccc, ddd) { if (arguments.length < 4) { var aaa = null; } if (arguments.length < 5) { var bbb = null; } if (arguments.length < 6) { var ccc = null; } if (arguments.length < 7) { var ddd = null; } // possibly now check if aaa == null, set it to true, or 7, or something // ... }

Note that if the function caller doesn't give those extra arguments, their corresponding variables (e.g. bbb) will remain undefined in the function, which is a little strange. So you have to declare them with var. Now let's see a version of this which is actually slightly faster because it uses fewer comparisons. This wouldn't really be noticeable in most cases but might be noticeable if you loop and do this a thousand times.

// In this function, aaa, bbb, ccc, and ddd are meant to be optional function HasExtraParameters(thingOne, thingTwo, thingThree, aaa, bbb, ccc, ddd) { if (arguments.length < 4) { var aaa = null; var bbb = null; var ccc = null; var ddd = null; } else if (arguments.length < 5) { var bbb = null; var ccc = null; var ddd = null; } else if (arguments.length < 6) { var ccc = null; var ddd = null; } else if (arguments.length < 7) { var ddd = null; } // possibly now check if aaa == null, set it to true, or 7, or something // ... }

Why does this use fewer comparisons? It has four if-statements, after all. Well, they are in the else-if format. If the first if-statement is true, it will not bother checking all of the rest; if the second one is true, it will not bother checking all the ones subsequent; etc.

5.5.2. Recognizing variadic functions in documentation

Fairly often, you will see an official documentation page for a varaidic function. These may be notated with explicit phrases like "Optional" next to the parameters. However, there is a shorthand which is conventional for denoting optional parameters: a set of square brackets is placed around the parameter(s). For example:

  • aFunction(aParam, anotherParam[, anOptional])
  • aFunction(aParam, anotherParam[, firstOptional[, secondOptional]])

5.6. Functional programming

Functional programming is a style of programming, supported by features of the programming language, in which functions can be passed around as if they are variables. JavaScript is one of the few popular languages to support this. We will see how it can give a number of benefits, including primarily modularity of functions for different purposes.

5.6.1. Modularity: definition & benefits

If a system is modular, it has interchangeable parts. A good example is a vacuum cleaner and its attachments. A vacuum cleaner can have any kind of attachment on the hose: a brush, a horizontal bar, a triangular head, etc., and the vacuum does not know or care any details of the attachment. You could even upgrade the vacuum and the attachments don't need to know or care that anything has changed. They meet in the middle, using a common interface (a cylindrical tube), and they require very few specifics of each other in order to function.

Software systems can also be modular, and in fact, this kind of interchangeability is one of the most consistently desirable goals in software design. A more formal term for this mutual lack of dependency is decoupling, which is also seen in engineering.

5.6.2. First examples

Let's say you want to take an array of persons' names and transform them somehow: let's say that right now, you want to convert them to uppercase. We'll start with a program like this:

function ConvertAStringToUppercase(aString) { return aString.toUpperCase(); } function ConvertAllStrings(anArray) { for (var i = 0; i < anArray.length; i++) { anArray[i] = ConvertAStringToUppercase(anArray[i]); } } var someNames = ["Bob", "Jeff", "Andy"]; ConvertAllStrings(someNames); // now they will all be uppercase // (remember "reference semantics" of arrays)

We have two nice functions, and the ConvertAllStrings() function is decent - it performs a useful task - but it is tightly coupled with the ConvertAStringToUppercase() function. Put another way: the ConvertAllStrings() function only knows how to transform strings in one way (to uppercase), because it uses ConvertAStringToUppercase() (which may also be seen as a dependency on that second function). What if we could make ConvertAllStrings() a more general-purpose function: one that knows how to iterate over an array and change each of its elements according to any given transformation, not just convert to uppercase?

We can do this, in fact. Let's see the next step:

function ConvertAStringToUppercase(aString) { return aString.toUpperCase(); } function ConvertAllStrings(anArray, whichFunctionToCall) { for (var i = 0; i < anArray.length; i++) { anArray[i] = whichFunctionToCall(anArray[i]); } } var someNames = ["Bob", "Jeff", "Andy"]; ConvertAllStrings(someNames, ConvertAStringToUppercase); // now they will all be uppercase // (remember "reference semantics" of arrays)

In this example, we tell ConvertAllStrings() which function to call. It no longer has any explicit mention of uppercase strings. Our function has a parameter which it uses as a function (whichFunctionToCall), so in that sense, the function to be called becomes a variable like any other variable. Now, you can choose any number of transformations with a minimal change of code and no change to ConvertAllStrings():

function ConvertAStringToUppercase(aString) { return aString.toUpperCase(); } function ConvertAStringToLowercase(aString) { return aString.toLowerCase(); } function ConvertAStringToItsFirstLetter(aString) { if (aString.length > 0) { return aString[0]; } else { return ""; } } function ConvertAllStrings(anArray, whichFunctionToCall) { for (var i = 0; i < anArray.length; i++) { anArray[i] = whichFunctionToCall(anArray[i]); } } var someNames = ["Bob", "Jeff", "Andy"]; ConvertAllStrings(someNames, ConvertAStringToUppercase); // Or: take your pick of other compatible functions // ConvertAllStrings(someNames, ConvertAStringToLowercase); // ConvertAllStrings(someNames, ConvertAStringToItsFirstLetter);

So these functions are interchangeable - why? Simply because they take one parameter and they return a string, in this case. There are not any other demands on them which all candidate functions must meet. Some languages have a much more formal way of guaranteeing that different functions are compatible for the same purpose. JavaScript has no such formalism, so you can really use any function you want and hope it works.

5.6.3. With anonymous functions

You can also make a new function on the fly and use it instead of specifying a function name. For example:

function ConvertAllStrings(anArray, whichFunctionToCall) { for (var i = 0; i < anArray.length; i++) { anArray[i] = whichFunctionToCall(anArray[i]); } } var someNames = ["Bob", "Jeff", "Andy"]; // Quick, single-line function: ConvertAllStrings(someNames, function(aParam){ return aParam.toLowerCase(); }); // Multi-line function; no difference in structure, really: ConvertAllStrings(someNames, function(aParam){ var theParamStringLength = aParam.length; // hope it's a string.. var theParamFirstLetter = aParam[0]; return theParamFirstLetter + "/" + theParamStringLength; // returns "D/5" from "David" });

These kinds of functions are called anonymous functions. You may notice that the declaration is exactly like a regular function except that the name is missing.

You can use an anonymous function anywhere a function is expected, which is typically in the case of a function being expected as an argument to another function, like these examples. It may be cleaner or easier to do this than to have to declare a function and think of a name for every one.

To further expand on this subject.. the following two snippets of code have identical effect:

function FindTheAverage(anArray) { // ... }
var FindTheAverage = function(anArray) { // ... }

In fact, some JavaScript experts think that function declarations should be taught that way from day one, as a means of showing that functions can be passed around just like variables.

5.6.3.1. As "closures"

What's the benefit of making an anonymous function, again? One benefit may be convenience. Another benefit is this: the ability to tie in outside variables from the immediately surrounding context. This is an advanced topic, especially if you consider all of its implications, but the first examples are not too bad; try to understand them.

// An example that may be used for the decidingFunction below, although // we do not use it; this allows values greater than 10 (returns true for // them) and disallows all others. function ExampleDecidingFunction(aParam) { return (aParam > 10); } // Returns a new array with only the elements of anArray which are allowed // by decidingFunction: the function must return true when passed the // array element function KeepOnlyValidElements(anArray, decidingFunction) { var newArray = []; // Iterate through the given array and test each element for (var i = 0; i < anArray.length; i++) { // Get the current array element; for convenience var currentElement = anArray[i]; // Give the element to the deciding function; // if it returns true, include this element in the // output array if (decidingFunction(currentElement)) { newArray.push(currentElement); } } // Return the new array return newArray; } // Example 1: // Returns a new array with the elements of anArrayOfNumbers which are // greater than or equal to the given threshold function LimitArrayToThreshold(arrayOfNumbers, treshold) { return KeepOnlyValidElements(arrayOfNumbers, function(anElement) { return (anElement >= treshold); }) } // Example 2: // Returns a new array with the elements of anArrayOfStrings which // have a string length greater than or equal to the given threshold function LimitArrayToStringLengthThreshold(anArrayOfStrings, lengthTreshold) { return KeepOnlyValidElements(anArrayOfStrings, function(anElement) { return (anElement.length >= lengthTreshold); }) }

In the snippet above, we have two examples of use of anonymous functions. In both cases, we capture some information from the immediately surrounding context, such as the variable threshold, and incorporate it into the anonymous function. So we could even take this variable from user input (e.g. "Enter the minimum string length you want") - all while maintaining the modularity of functional programming. Pretty neat stuff.

There is certainly more you can do with closures and you may run into strange problems during your experimentation. However, other people have run into the same problems. Ask your question on Google or Stack Overflow and you will probably get your answer.