Lesson Weekend

Now that we have an understanding of JavaScript objects, let's put them to work! In the next few lessons, we'll build an address book app to store contact info for our friends.

Since each contact will have multiple properties, we will use Contact objects to encapsulate their data. And because all Contacts should have the same combination of properties (name, phone number, etc.) we'll create a constructor that can quickly craft many different Contact objects with this same structure.

We'll focus only on the business logic for now. Then we'll build code for the user interface together in upcoming lessons.

Project Setup

First, let's create a project directory called address-book. It will contain a js subdirectory to house JavaScript logic, with a single JavaScript file called scripts.js inside. Like all project, we'll also include a README.md.

Our project structure should look like this:

address-book
├── js
│   └── scripts.js
└── README.md

Again, we'll wait to add user interface logic (that is, any jQuery, HTML, and anything else meant to create the user-facing portion of the app) until after we've written our business logic.

Constructor

We'll start by building a simple Contact constructor in scripts.js:

scripts.js
function Contact(firstName, lastName, phoneNumber) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.phoneNumber = phoneNumber;
}

Let's test this code! Refresh the browser's console (if you haven't already). Then can copy/paste the constructor above into the browser's JavaScript console, then recreate our instance of Contact by running the following:

let testContact = new Contact("Ada", "Lovelace", "503-555-1111");

If we check the value of testContact (by typing testContact into the console, and hitting Enter), we'll see the following response appear:

Contact {firstName: "Ada", lastName: "Lovelace", phoneNumber: "503-555-1111"}

This means our object has been successfully saved! The console remembered the Contact object we created and associated with the testContact variable name. And that Contact object contains all the properties we provided our constructor.

Accessing Object Properties

We can also access our object's individual properties. For instance, we can type the following into the console:

testContact.lastName;

And it will return the lastName property we instantiated our Contact object with:

"Lovelace"

Notice we don't use parentheses after lastName. This is because it's a property of the object, not a method being called upon it. This same syntax will work for the other object properties too. For instance, we could call testContact.firstName or testContact.phoneNumber to see other properties. If we were to add (), we'd get an Uncaught TypeError: ... is not a function error. While it's easy to get mixed up at first, properties are not methods!

Prototype

Next, let's create a simple prototype method to call on Contact objects. Let's say we want a fullName() method to return the contact's first and last name concatenated together.

We can define a new prototype function in our scripts.js file like this:

scripts.js
function Contact(firstName, lastName, phoneNumber) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.phoneNumber = phoneNumber;
}

Contact.prototype.fullName = function() {
  return this.firstName + " " + this.lastName;
};

By the way, if you still have any confusion about semicolons, let's go over this again one more time because the example above illustrates the difference with defining functions. In the first example, we begin with the function keyword. Functions don't have semicolons after the closing curly brace.

However, in the second function, we are assigning a function to a property of the Contact.prototype. It's like assigning a value to a variable. That means we add a semicolon to the end.

It's all a bit arbitrary, really, since JavaScript doesn't really care. As we mentioned in Introduction to Programming, the JavaScript interpreter will automatically insert semicolons where needed so our machines can properly read our code. However, the interpreter isn't perfect and there are some fairly obscure situations where JavaScript can get things wrong. Beginners can definitely run into these situations and it's difficult to debug if you don't know what's happening. That's why we are adding semicolons instead of having JavaScript do it automatically - because it's hard for beginners to know those weird situations when JavaScript won't do it automatically for us. By the way, many companies (such as Airbnb) require semicolons in their consistency standards while many others don't. While we require semicolons and consistency at Epicodus, you may not be using semicolons at a future job.

We can copy/paste the contents of scripts.js into the JavaScript console again and create another sample Contact by invoking our constructor with the following code:

let testContact = new Contact("Ada", "Lovelace", "503-555-1111");

After that, we can call our new method in the console like this:

testContact.fullName();

It will return the object's firstName and lastName properties concatenated together:

"Ada Lovelace"

Note that we need to use parentheses when we call our fullName() method, because it is a method on the object, not a property. Also, it's important to remember that this method can only be called on Contact objects.

Now that we've created a constructor for Contact and a simple prototype method that can be called on Contacts, let's move on to constructing the address book itself.


Example GitHub Repo for the Address Book

Examples


Creating a Contact constructor:

function Contact(firstName, lastName, phoneNumber) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.phoneNumber = phoneNumber;
}

Creating a prototype method on our constructor:

Contact.prototype.fullName = function() {
  return this.firstName + " " + this.lastName;
};

Example GitHub Repo for the Address Book

Lesson 5 of 32
Last updated April 8, 2021