Historical Context & Motivation
Before computers existed, people kept contact information in physical address books — small notebooks where you could flip to a letter tab and find someone's phone number. As software replaced paper, developers needed a way to represent that same structured data inside a program. The challenge was finding a format that was easy for both humans to read and machines to parse. That search led to JSON (JavaScript Object Notation), a lightweight data format that mirrors how JavaScript already organizes information.
Today, almost every app you use — from your phone's Contacts to Snapchat — stores and exchanges data in JSON or a similar format. The question this lesson addresses is straightforward: How do you build, search, and update a collection of structured records using JavaScript arrays and objects? By building a simple address book, you will learn patterns that apply to any data-driven project.
Core Principles & Definitions
Before you write any code, you need to understand the building blocks. An address book is really just a list of contacts, and each contact has several fields — name, phone, email, and so on. JavaScript gives you two key structures to model this: objects (which hold labeled fields) and arrays (which hold ordered lists). When you combine them — an array of objects — you get a simple but powerful data model.
Object
{ }. Each key is a string label (like "name"), and each value can be a string, number, boolean, or even another object.Array
[ ]. Each item has a numeric index starting at 0. Arrays let you group many items of the same type together.Array of Objects
Lookup (Search)
.find() and .filter() to make this easy.Update (Mutate)
Visual Explanation — The Address Book Structure
addressBook array containing three contact objects at indices 0, 1, and 2. Each object has the same four keys: name, phone, email, and city. The amber box demonstrates a lookup using .find(), and the green box shows a property update.Notice that every contact object follows the same shape — the same set of keys with different values. This consistency is what makes the array of objects pattern so useful. You can loop through the array, compare a field, and confidently access any property you need because you know every object has it. The lookup finds the matching object by its name, and the update modifies a single property on that same object reference.
How It Works — CRUD Operations
Most data-driven programs revolve around four operations known by the acronym CRUD: Create, Read, Update, and Delete. Your address book uses the same operations. Let's map each one to the JavaScript code you will write.
Create — Adding a Contact
To add a new contact, you build an object literal and push it onto the array. The .push() method appends the item to the end. Here is the pattern:
addressBook is the array. .push() adds the new object at the next available index.Read — Looking Up a Contact
The .find() method accepts a callback function and returns the first object where the callback returns true. If no match exists, it returns undefined.
contact => contact.name === "Bob Chen" checks each object's name field. result will hold the matching object or undefined.Update — Changing a Field
Once you have a reference to the object (from .find()), you can change any property using dot notation or bracket notation. The original object inside the array is modified because objects are stored by reference.
phone property. You can also use bracket notation: result["phone"] = "555-9999".Delete — Removing a Contact
You can remove a contact by finding its index with .findIndex() and then using .splice() to cut it out. Alternatively, .filter() returns a new array that excludes the unwanted entry.
Detailed Breakdown — Data Flow Diagram
Understanding the flow of data through your program is just as important as knowing the syntax. When a user wants to find or change a contact, the program follows a clear sequence: receive input, search the array, act on the result, and provide output. The diagram below visualizes this flow for both lookup and update operations.
.find() returns undefined, trying to access a property on it (like result.phone) will crash your program with a TypeError. Always wrap updates in an if (result) check first.Worked Example — Building the Address Book
Let's build a complete mini-project from scratch. We will create an address book, add contacts, look one up by name, update their phone number, and then list everyone in a specific city.
name, phone, email, and city.let addressBook = [
{ name: "Alice Lee", phone: "555-0101", email: "alice@mail.com", city: "Austin" },
{ name: "Bob Chen", phone: "555-0202", email: "bob@mail.com", city: "Denver" },
{ name: "Cara Diaz", phone: "555-0303", email: "cara@mail.com", city: "Austin" }
];.find() to search for Bob Chen. The callback compares each contact's name to the target string. Because "Bob Chen" exists at index 1, bob will hold a reference to that object.const bob = addressBook.find(c => c.name === "Bob Chen");
console.log(bob);
// { name: "Bob Chen", phone: "555-0202", email: "bob@mail.com", city: "Denver" }.find() returns undefined, and accessing a property on undefined would throw an error.if (bob) {
console.log("Found:", bob.name);
} else {
console.log("Contact not found.");
}if block, assign a new value to bob.phone. Because bob is a reference to the object inside addressBook, the array is updated too — no copy was made.bob.phone = "555-9999";
console.log(addressBook[1].phone);
// "555-9999" ← updated in the original array.filter() to get all contacts in Austin. Unlike .find(), which returns one object, .filter() returns a new array containing every match.const austinContacts = addressBook.filter(c => c.city === "Austin");
console.log(austinContacts.length); // 2
// [{ name: "Alice Lee", ... }, { name: "Cara Diaz", ... }]Array Methods — Strengths & Limitations
JavaScript offers several array methods that are useful for address book operations. Each method has trade-offs, so choosing the right one depends on what you need to accomplish. The table below compares the key methods you will use most often.
| Method | Returns | Best For |
|---|---|---|
.find() | First matching object (or undefined) | Looking up a single contact by a unique field like name |
.filter() | New array of all matches (empty array if none) | Getting all contacts in a city, or matching a partial search |
.findIndex() | Index number (or −1) | When you need the position for .splice() to delete |
.push() | New length of the array | Adding a new contact to the end of the array |
.splice() | Array of removed items | Removing a contact at a specific index (mutates the array) |
.forEach() | undefined | Looping through every contact to display or log |
.find() like using Ctrl+F to jump to the first match, and .filter() like highlighting every match on the page.Connection to Advanced Concepts
The JSON address book you are building is a simplified version of the data layer found in real applications. As you advance, the same concepts scale up dramatically. The table below shows how each element of your project maps to professional tools and techniques.
| This Lesson | Advanced Version |
|---|---|
| Array of objects stored in a variable | Database table (SQL) or document collection (MongoDB) |
.find() for lookup | SQL SELECT ... WHERE query |
| Dot notation to update a field | SQL UPDATE ... SET statement |
.filter() for multiple matches | REST API endpoints with query parameters |
| Data stored in memory (lost on refresh) | Persistent storage with localStorage, files, or cloud databases |
One natural next step is learning JSON.stringify() and JSON.parse(), which convert your array to a text string and back. This lets you save the address book to localStorage so it persists between browser sessions. Eventually, you will connect your front-end code to a back-end server and a real database — but the mental model of CRUD on an array of objects stays exactly the same.
Practice Problems
.find() and .filter() when searching an address book array. When would you choose one over the other?let contacts = [
{ name: "Dana Kim", phone: "555-1111" },
{ name: "Eli Fox", phone: "555-2222" }
];updateEmail(addressBook, name, newEmail) that finds a contact by name and updates their email. If the contact is not found, the function should return the string "Contact not found". If the update is successful, return the updated contact object.name, grade (a number 9–12), and email. Write code that: (1) creates an array with at least 3 students in different grades, (2) filters to get only 10th graders, and (3) logs each 10th grader's name and email to the console..find() to look up by name could be a problem, and propose at least two different strategies to handle this situation.Lesson Summary
In this lesson you learned how to model structured data using an array of objects — the foundational pattern behind nearly every data-driven application. Each contact in the address book is a JavaScript object with key-value pairs for name, phone, email, and city. The collection of contacts lives inside an array, giving you ordered, indexed access to every record.
You practiced the four CRUD operations: Create with .push(), Read with .find() and .filter(), Update with dot notation on the found object, and Delete with .filter() or .splice(). Always guard against undefined when a lookup finds no match. These skills transfer directly to databases, APIs, and every professional tool you will encounter as you advance in programming.