{ JavaScript for Behavior. }

Objectives

By the end of this chapter, you should be able to:

  • Explain what JavaScript is
  • Utilize primitives, objects, and functions
  • Use boolean logic with conditional statements

Introduction

So, what's JavaScript? JavaScript is a programming language that is essential for web development. If you think of any web page you interact with today, JavaScript is most likely providing the action on the page. JavaScript can be used to change the status of a button when it is clicked on, create a chat window at the bottom of your screen, or even create a web-based game. With modern tools like Node.js, JavaScript can now also be used to save data to a database or to create desktop applications. The applications are limitless, and we're excited to see what you'll create. Along with HTML and CSS, JavaScript is one of the three major tools you'll need to understand if you want to build a modern website. While this course won't focus on HTML or CSS, a little later on we'll show you how to include JavaScript in a basic HTML file.

JavaScript and HTML in 2 Separate Files

Another option is to keep your HTML and JavaScript in separate files. This is a better practice, especially as your HTML and JavaScript files get longer. To do this, you still need to include a script tag in your HTML, but now this tag should link to a separate JavaScript file. Here's how you could do that if you have a file called first.js:

<!DOCTYPE html>
<html>
<head>
<title>JavaScript Test Site</title>
<script src="first.js"></script>
</head>
<body>

<p>Nothing going on yet.</p>

</body>
</html>

In this case, we also need a additional JavaScript file called first.js! So create this file, and inside of it write some JavaScript. Maybe it looks like this:

alert("Coming to you from first.js!");

As before, the code should execute as soon as you open the HTML page in Chrome.

Variables and Data Types

Variables

What's a variable, and why would you ever want to use one? The word "variable" may be most familiar to you from math class, when you often use letters like x or y to represent numbers.

This idea also exists in programming languages. Using variables lets us write code that's easier to read and also easier to change. It's unlikely you'll ever write a significant amount of JavaScript code without using variables, so it's good to get used to them early.

To see why variables are useful, suppose you want to log a set of greetings to the console:

console.log("Hi, Matt!");
console.log("How are you doing, Matt?");
console.log("See you later, Matt!");

This works fine, but what if we want to change the person's name from "Matt" to something else? We'll have to change three different spots in our text file, and there's a risk that we'll make a typo when fixing any one of these changes. Wouldn't it be better if we could just store a single copy of the name, and use it wherever we want?

Variables give us this ability. So let's write our first variable. In JavaScript, you initialize variables using the var keyword. Strictly speaking, using this keyword is not necessary, but in practice it should almost always be there (we'll discuss why a bit later).

Let's rewrite the example above to use a variable:

var firstName = "Matt";
console.log("Hi, " + firstName + "!");
console.log("How are you doing, " + firstName + "?");
console.log("See you later, " + firstName + "!");

If you enter this code correctly, you should see the same result as before - JavaScript knows that firstName corresponds to the name Matt!

There are a few different things going on here, so let's unpack the code a bit. On the first line, we're declaring a variable using the var keyword. A variable is just a way for us to save some data in JavaScript. When we typed in var firstName = "Matt", JavaScript stored the word Matt in the variable firstName. From then on, any time you use firstName in the console while this window is still open, you'll see the value that firstName has stored.

On the subsequent lines, you'll see there's something else going on too: we're using the + operator to combine words made up of characters, or strings, together. In JavaScript, when you combine two strings with the + operator, you get a new string which is a combination of the two. You can think of this as adding the strings together; a more formal name for it is concatenation. For example, if you write the expression "Hello" + " World" in the console, you should see that the result is the single string "Hello World".

Let's declare some more variables.

var firstName = "Matt";
var lastName = "Lane";
var fullName = firstName + " " + lastName;

In all of these examples, we have the keyword var in front, followed by the variable name, an assignment operator (the = sign), and then the value we want to assign to our variable.

These examples also illustrate a common convention when writing JavaScript: when declaring variables using multiple words, the standard is to capitalize each word after the first word, and otherwise use lower-case letters (e.g. firstName, not firstname, first_name, FirstName, or some other variation). This casing convention is called camel case, and while your JavaScript code will work just fine if you don't abide by this convention, it's good to get in the habit of camel casing your variables.

Primitive Data Types in JavaScript

So far, we've only used variables to store strings. But JavaScript can work with other types of data as well. Let's take a look at the primitive data types (you don't need to worry about what primitive means just yet).

JavaScript has 6 primitive data types, but we'll only talk about 5 of them. Here's what they look like:

  • string - var greeting = "hello";
  • number - var favoriteNum = 33;
  • boolean - var isAwesome = true;
  • undefined - var foo; or var setToUndefined = undefined;
  • null - var empty = null;

JavaScript is known as a "weakly" typed language. What this means is that when you create variables and assign them to values, you do not have to specify the type of data you are working with. In statically (or strongly) typed languages, like Java and C++, you do need to specify the type.

Now let's look at data types a little more.

string

As we saw above, a string is a set of characters enclosed in quotes. A string can be defined using double quotes:

var greeting = "Hello Whiskey";

or using single quotes:

var greeeting = 'Hello World';

So what is the difference between the two ways of initializing a string? Well, first of all, if you want quotes in your string, it's nice to have another option to start and end the string:

var phrase = 'Matt said, "I haven\'t been to Chile", the other day.';

What would happen if you try to use double quotes to create the previous string instead of using single quotes? Try it in your console.

Also notice that there is a backslash before the single quote in haven't. The backslash is called an escape character and it tells JavaScript that the single quote in the string should not be used to end the string. Try removing the backslash from the string and seeing what happens in your JavaScript console.

number

JavaScript numbers can be positive:

var num = 5;

negative:

var num = -25;

decimal numbers:

var piApproximation = 3.14159265;

and we can also do all of the math expressions you'd expect:

var x = 1 + 3;
var a = 4.5;
var b = 5.9;
var c = Math.sqrt(a * a + b * b);
var studentTeacherRatio = 4 / 1;

If you need to do any kind of calculation in the application you're building, chances are you'll be relying heavily on the number type.

boolean

A boolean type can only be in one of two states, true or false. In other words:

var pizzaIsGood = true;
var pizzaIsBad = false;

Boolean types are a very useful tool for controlling our program. For example, if a user is signed in, you might want to show them a link to update their profile; but if a user is not logged in, you'd probably just want to show them a sign-in link. This sort of behavior, where the code that gets executed is conditioned on something else, happens all the time in programming. We'll learn more about how to deal with these situations in the next chapter.

undefined

Any variable that is created in JavaScript that is not assigned a value is undefined:

var noValue;  // The value here will be undefined

You can also explicitly set a variable to undefined:

var favoriteFood = "Candy";
// Changed your mind
var favoriteFood = undefined;

null

Null is not the same as undefined. It signifies an intentional absence of data.

var secondEmailAddress = null;

It is important to remember that null and undefined are different types in JavaScript! This can be a confusing feature of JavaScript, even for people who know other programming languages. The distinction can seem somewhat arbitrary when you're first learning the language, but as you get more comfortable the distinction will become clearer. For now, you don't need to worry about it too much; if you're interested, you can read some discussion about the differences here and here.

Conditional Logic

An essential part of writing programs is being able to execute code that depends on certain conditions. There are many different examples when you'd want to conditionally execute code. Here are just a few:

  • You want the navigation bar on your website to look different based on whether or not someone is logged in
  • If someone enters their password incorrectly, you want to let them know; otherwise, you want to log them in
  • You're building a tic-tac-toe game, and want to know whether it's X's turn or O's turn
  • You're building a social network and want to keep person A from seeing person B's profile unless the two of them are friends

And so on, and so on. It's very hard to write any kind of interesting software without making use of conditionals and boolean logic.

So let's talk about how to write conditional logic in JavaScript. To do so, we'll make use of booleans (true and false), along with if statements and switch statements.

An if statement looks something like this:

var instructor = "Elie";

// we begin with an "if" statement followed by a condition in () and a block of code inside of {}
if(instructor === "Elie") {
    console.log("Yes!");
} else {
    console.log("No");
}

Notice that we used a === instead of =. Anytime that we use more than one equals operator (we can either use == or ===) we are doing what is called comparison (comparing values). When we use a single equals operator =, we are doing what is called assignment (setting a variable equal to some value).

This first example might appear a little strange, because the condition inside of the if statement (instructor === "Elie") will always return true! Here's another example for you to consider. Run this code a couple of times and try to get both messages to log to the console based on what you enter into the prompt:

var favoriteFood = prompt("What's your favorite food?");

if(favoriteFood === "pizza") {
    console.log("Woah! My favorite food is pizza too!");
} else {
    console.log("That's cool. My favorite food is pizza.");
}

(If you're having trouble getting the first message to log, it may help to know that strings are case-sensitive: "pizza" and "PIZZA" are different strings.)

Now, what's the difference between == and ===, you ask? Great question! We'll get to that down below. For now, though, it might be helpful to play around with these operators in the Chrome console, and see if you can come up with a guess as to how these operators behave differently.

var number = 55;

// we begin with an "if" statement followed by a condition in () and a block of code inside of {}
if(number == "55") {
    console.log("Yes!");
} else {
    console.log("No");
}

Difference between == and ===

In JavaScript we have two different operators for comparison: the double and triple equals. Both operators check whether the two things being compared have the same value, but there's one important difference. == allows for type coercion of the values, while === does not. So to understand the difference between these operators, we first need to understand what is meant by type coercion.

Consider the following examples:

// 1.
5 + "hi"; // "5hi"

// 2.
if ("foo") {
  console.log("this will show up!");
}

// 3.
if (null) {
  console.log("this won't show up!");
}

// 4.
+"304"; // 304

Let's figure out what's happening in each of these examples. In the first one, you've asked JavaScript to add a number and a string. In a lot of programming languages, this would throw an error, but JavaScript is more accomodating! It evaluates the expression 5 + "hi" by first coercing 5 into a string, and then interpreting the "+" operator as string concatenation. So it combines the string "5" with the string "hi" into the string "5hi".

The next two examples show a similar sort of coercion. JavaScript expects the values inside of parentheses that come after the keyword if to be booleans. If you pass in a value which is not a boolean, JavaScript will coerce the value to a boolean according to the rules for truthy/falsey values defined below. Since "foo" is not a falsey value, it will be coerced to true, which is why the second example logs something to the console. null, however, is a falsey value, so it gets coerced to false and nothing shows up in the third example.

The last example shows a very common way to coerce a stringified number back into a number. By prefacing the string with the plus sign, JavaScript will perform a coercion on the value and convert it from a string value to a number value.

In essence, then, coercion is just the process of converting a value from one type to another. JavaScript uses coercion pretty liberally among programming languages, so if you don't understand how coercion in JavaScript works, it can be easy to introduce bugs into your code.

But what does all of this have to do with == and ===? Let's look at some examples:

5 == "5"; // true
5 === "5"; // false
"true" === true; // false
"true" == true; // false
true == 1; // true
true === 1; // false
undefined === null; // false
undefined == null; // true

What's going on here? Let's deal with the expressions involving === first. As you can see, the expressions 5 === "5", "true" === true, true === 1, and undefined === null all evaluate to false. In some sense, perhaps this shouldn't be so surprising: none of the values being compared are the same! One way to think about this is to recall the types of the primitives being compared. In the first case, we're comparing a number to a string; in the second case, a boolean and a string; in the third case, a boolean and a number; and in the last case, undefined and null. How can these values be the same when the primitives involved aren't even of the same type??

From the above examples, you can see that the == operator is a little less strict (in fact, === is sometimes referred to as the "strict" equality operator, while == is sometimes referred to as the "loose" equality operator). The reason that comparisons like 5 == "5" evaluate to true is because == allows for type coercion!

But what gets coerced? Does 5 become "5" or does "5" become 5? In this case, according to the specification the string gets coerced into a number, not the other way around. This might seem like an unimportant detail, but there are a couple of gotchas in the way coercion works that can be confusing when you first encounter them.

For example, it might seem like "true" == true should evaluate to true, since "true" is a truthy value! But in fact, what actually happens is that the boolean true gets coerced to a number (1), and then "true" is compared to 1, which returns false. (This is also why true == 1 evaluates to true.)

It's less important to memorize these rules for how coercion works with == than to recognize that == allows for coercion while === doesn't. If you don't want to have to think about coercion in your comparisons, stick to ===.

If / else statements with other comparators

We previously saw what an if statement looks like. Let's examine this a bit more:

var x = 4;
if(x <= 5){
    console.log("x is less than or equal to five!");
} else {
    console.log("x is not less than or equal to five!");
}

We saw before that we can use == or === to compare values. We can also check for inequality, using

< - less than,

<= - less than or equal to,

> - greater than,

>= - greater than or equal to,

!= - not equal (loose), and

!== - not equal (strict).

Arrays and Objects

So far, we've seen five different primitive data types in JavaScript: string, number, boolean, null, and undefined. We've also seen how to store these values inside of variables.

Sometimes, however, you need a more complex data structure when building your application. For example, maybe you need a list of restaurant names so that you can display each one to a user when she's looking for a place to eat nearby. Or maybe you're doing some math and want to maintain a list of prime numbers. It would be pretty annoying to have to write

var firstPrime = 2;
var secondPrime = 3;
var thirdPrime = 5;
var fourthPrime = 7;
var fifthPrime = 11;

This is fine if you know how many primes you need at the outset, but what if you didn't know how many values you needed to store? Or what if you did know how many values you needed, but the number was quite large? Writing out a variable for each one can quickly become unmanageable.

Thankfully, JavaScript provides you with a data type to help in these situations: the array. You can think of an array as simply a list of values.

To write an array in JavaScript, you use square brackets [] and comma separate each value in the array. Here are some examples:

var primes = [2, 3, 5, 7, 11];
var names = ["Alice", "Bob", "Charlie"];
var booleans = [true, false, false, true];
var mixedTypes = [1, "sweet", true, null, NaN, "bye!"];
var woahhh = ["What's up with this? -->", ["Woah", "crazy!"]];
var emptyArray = [];

You can put anything you want inside of an array: numbers (as in primes), strings (as in names), booleans (as in booleans), and other primitive types are all fair game. You can also have multiple different types inside of an array: just because the first element in an array is a number doesn't mean that every subsequent element needs to be a number too. For example, mixedTypes has many different types inside of it. You can even store arrays inside of other arrays, as in the woahhh array above!

At this point, you may be wondering why we didn't mention arrays when we talked about other data types in JavaScript. The reason is that up until now, we've been dealing with primitive data types in JavaScript. But arrays aren't primitives; they're examples of what's called a reference type. We'll talk about reference types in more detail in the next chapter. For now, it's sufficient to note that

typeof [1, 2, 3]

returns object. So arrays are a type of object, which we'll talk about in more general terms later.

Accessing and updating array values

To access an element in an array, we specify the name of the array followed by sqare brackets brackets and the position (also called the index) of the element we're trying to access. Arrays are zero-indexed, which means that the first element is accessed at index 0. Let's look at an example:

var arr = [5,3,10];
arr[0]; // should equal 5
arr[1]; // should equal 3
arr[2]; // should equal 10
arr[3]; // should be undefined -- remember, arrays are zero-indexed!
arr[1+1]; // the same as arr[2], which is 10
arr[arr.length-1]; // shorthand for the last element of an array, in this case 10

To update a value in an array, we can simply assign an element at a given index to a new value:

var arr = [5, 3, 10];
arr[0] = -1000;
arr[2] = "dope";
arr; // should be [-1000, 3, "dope"]

Adding to arrays

There are a number of ways you can add elements to an array.

One way is by setting a value at a new index in the array.

var arr = [1,2,3];
arr[3] = 4;
arr; // [1,2,3,4]

Be careful with this approach, though -- you can add an element at any index, and any elements that don't have values in them will be filled with undefined values.

var arr = [1,2,3];
arr[5] = "whoa";
arr; // [1, 2, 3, undefined, undefined, "woah"]

If you want to add to the end of an array, a better approach is to use the push function - this function returns the new length (the number of elements) of the array.

var arr = [3, 2, 5];
arr.push(7); // returns the new length, i.e. 4
arr; // [3, 2, 5, 7]

On the other hand, if you want to add to the beginning of an array, you can use the unshift function. As with push, unshift returns the length of the modified array.

var arr = [1,2,3];
arr.unshift(0); // returns the new length, i.e. 4
arr; // [0,1,2,3]

Removing from arrays

We've seen how we can add elements from arrays. But what about removing elements?

One (not common) way to remove elements is to manually set the length of the array to a number smaller than its current length. For example:

var arr = [1,2,3];
arr.length = 2; // returns the new length
arr; // [1,2]

A more common way to remove elements from the back of an array is to use pop(). This function works in sort of the opposite way as push, by removing items one by one from the back of the array. Unlike push, however, pop doesn't return the length of the new array; instead, it returns the value that was just removed.

var arr = [1,2,3];
arr.pop(); // returns 3
arr; // [1,2]

If you want to remove an element from the front of an array, you should shift() (like unshift, but the opposite)! As with pop(), shift() returns the removed value.

var arr = [1,2,3];
arr.shift(); // returns 1
arr; // [2,3]

There's also a delete keyword in JavaScript, which you might think could be used to delete elements in an array. However, this isn't quite how delete works with arrays. When you use this keyword, the value at the index where you delete will simply be replaced by undefined. This usually isn't what you want, which is why you won't often see people use delete on arrays. It's more common to see this word used with objects, which we'll talk more about in the next unit.

var arr = [5, 4, 3, 2];
delete arr[1];
arr; // [5, undefined, 3, 2]

In JavaScript, along with primitives we have objects. Objects allow you to map keys to values. For example, the key 'name' could map to "Tim". Or the key 'isInstructor' could map to the boolean true. These are example of key value mappings. When you want to know the name property of the object, you look it up and get the value back, which is "Tim" in this case. Here is an example of declaring an object:

var firstObj = {
    firstName: "Tim",
    lastName: "Garcia",
    isInstructor: true
};

In this object, we have keys of "firstName", "lastName", and "isInstructor" and values of "Tim", "Garcia", and true respectively.

Notice the format of an object. It has a key, followed by a colon, followed by a value, then a comma. But the last key and value in the object omits the comma. Forgetting the comma is an error that you may run into from time to time. Try putting the following in your console. You should see an error, Uncaught SyntaxError: Unexpected identifier, because there is no comma after the firstName key and value:

var firstObj = {
    firstName: "Tim"
    lastName: "Garcia",
    isInstructor: true
};

After we have created an object, the first thing we may want to do with it is access the values using the object's keys.

Accessing Object Values

To access values in an object, we could use the dot notation:

firstObj.firstName;       // returns "Tim"
firstObj.lastName;        // returns "Garcia"
firstObj.isInstructor;    // returns true
firstObj.keyDoesntExist;  // returns undefined

Or we could use the bracket notation:

firstObj["firstName"];       // returns "Tim"
firstObj["lastName"];        // returns "Garcia"
firstObj["isInstructor"];    // returns true
firstObj["keyDoesntExist"];  // returns undefined

We will learn the difference between these two later on.

Objects are one of the built-in types in JavaScript and consist of unordered key-value pairs. Let's look at another object:

var tim = {
    name: "Tim",
    catOwner: true,
    boatOwner: true
};

In the object above we have a set of keys (name, catOwner, boatOwner) and values ("Tim", true and true).

Functions

A function is a repeatable process of procedure. A real world analogy of a function is the brew button on a coffee machine. The coffee machine has inputs (hot water, and coffee grounds), and outputs (hot coffee). When you press the button to brew a pot of coffee, you are starting a process that should return an expected output to you. The same thing is true in programming. A function takes a set of variables as inputs and returns a value as an output.

We have already seen many functions in action. For example, in the array chapter, we learned about push and pop. These are both functions that operate on an array. Consider the following example:

var arr = [5,4,3,2,1];
var poppedVal = arr.pop();
console.log(arr);
console.log(poppedVal);

In the example, we are using the pop function. It takes no inputs, and it returns a value which is the last item in the array that has been removed from the array. When you run the code in your console, you'll see the array is now [5,4,3,2] and the value of poppedVal is 1.

Declaring Functions

So far we have only used functions, but to be a knowledgeable JavaScript programmer, we need to learn to write our own functions as well. There are multiple ways to write functions in JavaScript. We will cover the differences in more detail later. For now, let's start with one way: a function declaration.

In general, we declare a function in the following way:

function anyNameYouWantForTheFunction() {
    // As many lines of code as you want
}

In general, this type of function syntax consists of four parts:

  1. The function keyword,
  2. The name of the function (in this case, anyNameYouWantForTheFunction),
  3. Any parameters for the function (we'll ignore this for now, but parameters will go inside of the parentheses after the function name),
  4. The function body (the code for the function, which lives inside of the curly braces).

It might seem silly, but it would be good to practice typing this syntax out a few times. You'll be writing functions constantly in JavaScript, so the syntax is something you should commit to muscle memory. Try typing these out:

function myFunction() {
}

function myOtherFunction() {
}

function yetAnotherFunction() {
}

function okayIGetItThisIsTheSyntaxForFunctions() {
}

The functions above aren't very interesting, because none of them have a function body. Let's look at an example of a function that actually does something:

// this is called the function definition - we are ONLY defining the function here
function firstFunction(){
    console.log("I just wrote my first function!");
}

Now we have declared a function called firstFunction, but we have not used the function yet. To execute the code within the function, we must invoke the function. A function is invoked by adding a () after the name of the function:

// to call or invoke the function
firstFunction();

If you run this code in the Chrome console, you will see the output is "I just wrote my first function" and on the next line, undefined. Next, we'll learn where the undefined is coming from.

Returning Values From Functions

In JavaScript, if we do not specifically tell the function to return something, it will return undefined when it is finished executing. So how do we tell a function to return something? We use the return keyword!

// this is called the function definition -
// we are ONLY defining the function here
function firstFunction(){
    return "I just wrote my first function!";
}

// to call or invoke the function
firstFunction(); // now we don't see undefined anymore!

Now our function is returning "I just wrote my first function". To capture that string, let's use a variable:

var returnValue = firstFunction();
console.log(returnValue);

Now in the console, you should see "I just wrote my first function". That is the value that was returned from our function call and that is now saved in the returnValue variable.

Remember, the return keyword can ONLY be used inside of a function. let's take a look at another example.

function secondFunction(){
    return "Hello";
    return "Goodbye";
}

secondFunction(); // "Hello"

Learn More

When you're ready, move on to Putting it all Together

Continue

Creative Commons License