The Shape of Information
How Data Wants to Be Organized
You want to build an address book application. You need to store information about people: names, phone numbers, email addresses, maybe birthdays.
How do you organize this information?
Your first instinct might be individual variables:
const person1Name = "Alice";
const person1Phone = "555-1234";
const person1Email = "[email protected]";
const person2Name = "Bob";
const person2Phone = "555-5678";
const person2Email = "[email protected]";
This works fine. For two people. But what about twenty? Two hundred? And how do you loop through everyone when each person has a different variable name? The approach falls apart fast. It’s the programming equivalent of writing each friend’s address on a separate napkin and hoping you never have to find one in a hurry.
You need a better way to organize information. You need data structures.
Here’s the thing about data structures: they’re not just about storage. They’re about what questions you can easily ask. An array lets you ask “what’s the third item?” An object lets you ask “what’s the value for this key?” The structure you choose determines what’s easy and what’s painful. It’s the difference between a filing cabinet and a pile of papers on your desk. Both hold the same information, but only one lets you find something before lunch.
Describing your data clearly turns out to be one of the most important skills when working with AI coding assistants. “I have an array of objects, each with name, age, and email” gets you useful code. “I have some data about people” gets you the kind of code you smile at politely and then rewrite the moment it leaves the room.
Arrays: Keeping Things in Order
An array is a collection of items arranged in a specific order. Like a shopping list, a playlist, or a to-do list. (Python calls this same shape a list; JavaScript calls it an array. Same idea, different name.)
const fruits = ["apple", "banana", "cherry"];
This creates an array of three strings. Order is the whole point here: “apple” is first, “banana” second, “cherry” third, and the array will remember that forever, or until you say otherwise. Shuffle them and you have a different array, the way a deck of cards is a different deck after you cut it, even though not one card has left the table.
Accessing Items
You grab an item by its index, which is just its position in the array. And here is the first thing about programming that will quietly offend your common sense: counting begins at 0, not 1. It seems bizarre for about a week, then becomes so natural you start wondering why elevators don’t work this way.
Why start at 0? Historically, because indices are offsets from the beginning of the array in memory. The first item sits at offset 0. These days it’s mostly tradition, a deeply ingrained tradition found in nearly every programming language. Think of it as programmers’ long-running joke on everyone else, perpetuated for decades because changing it now would break approximately everything.
Some languages let you count backward from the end using negative numbers directly in brackets. JavaScript’s square brackets don’t do that — fruits[-1] doesn’t throw, it just quietly returns undefined, because brackets treat -1 as a property name, not a position, and no fruit lives at the property named -1. For counting from the end, arrays have a dedicated method instead:
Modifying Arrays
Arrays are mutable, which is a respectable-sounding word for “you can mess with them after you’ve made them.” Add an item, swap one out, throw one away, ask how many there are. The array doesn’t mind in the slightest. It was built to be fiddled with.
Looping Through Arrays
This is where arrays earn their keep. You can march through every item without knowing, or caring, how many there are. The loop variable takes on each value in turn, like a spotlight sliding across a stage and pausing on one performer at a time. You’ll meet this pattern everywhere for the rest of your programming life: get a pile of things, deal with each one, move on.
When to Use Arrays
Arrays suit situations where:
- Order matters
- Multiple items of the same kind exist
- Sequential processing is required
- Access by position is needed
Examples: a playlist, a history of moves in a game, a series of temperature readings, a to-do list. Anything that forms a natural sequence.
Objects: Looking Things Up
Arrays are wonderful when things belong in a line. But often you don’t care about position at all. You want to look something up by name. “What is Alice’s phone number?” is a perfectly normal thing to want. “What is the phone number of person number 47?” is the sort of question only a prison warden asks.
This is the purpose of objects. They store key-value pairs: a key (like a word in a dictionary) maps to a value (like the definition).
const person = {
name: "Alice",
age: 30,
city: "New York"
};
Here, name, age, and city are keys. “Alice”, 30, and “New York” are the corresponding values. The relationship is one of association: this key belongs with this value.
Accessing and Modifying Objects
You pull a value out by its key, either with a dot (person.name) or with brackets (person["name"]). Unlike an array, there’s no positional order to lean on. You never say “the second item in the object.” You say “the value sitting under this key.” The key is the address; the value is whatever lives there.
You can update a value, add a brand-new pair, or evict a key entirely. The object, like the array, fully expects to be rearranged.
When to Use Objects
Objects suit situations where:
- Lookup by name or identifier is desired
- Each item possesses distinct properties
- Order is not the primary concern (though JavaScript objects do preserve insertion order for the keys you’ll typically use)
- Related but different pieces of information must be grouped
Examples: a user profile, configuration settings, a phone book, word frequency counts. Anything that answers questions of the form “what is the X for Y?”
Think of objects as labeled boxes. Each box has a label (the key) and contains something (the value). When you want the contents, you just need to know the label. Whether it’s the third box or the seventh doesn’t matter. The label is all you need, and suddenly organization becomes someone else’s problem.
Arrays vs. Objects: Choosing the Right Tool
This is one of the genuinely fundamental decisions in programming, and you’ll make it constantly: which shape fits the data in front of you?
Use an array when:
- Multiple similar items exist
- Order matters
- Sequential processing is intended
- Example:
const scores = [85, 92, 78, 95];
Use an object when:
- Different kinds of information describe one thing
- Lookup by name is needed
- Order is not the primary concern
- Example:
const student = { name: "Alice", grade: 85, year: "sophomore" };
Sometimes you need both. That’s perfectly fine. Nest them, combine them, interweave them as your data demands.
Combining Structures
Real data is rarely flat. Out in the wild you’ll find arrays of objects, objects stuffed with arrays, and combinations with enough floors and stairwells that you start leaving a hand on the banister.
Array of Objects
const students = [
{ name: "Alice", grade: 85 },
{ name: "Bob", grade: 92 },
{ name: "Charlie", grade: 78 }
];
This is an array of three items, each of which is an object. It’s a pattern you’ll see as often as queues at a post office: multiple records, each sharing the same structure. A classroom roster, a product catalog, a collection of users.
You can loop through it:
for (const student of students) {
console.log(`${student.name} scored ${student.grade}`);
}
Output:
Alice scored 85
Bob scored 92
Charlie scored 78
Object with Array Values
const grades = {
Alice: [85, 90, 88],
Bob: [92, 95, 91],
Charlie: [78, 82, 85]
};
Each key is a name, and each value is an array of that person’s grades. The object provides lookup by name; the array provides the history.
Access a specific grade:
console.log(grades["Alice"]); // [85, 90, 88]
console.log(grades["Alice"][0]); // 85 (Alice's first grade)
First the key “Alice” is looked up, yielding an array. Then the first item in that array is accessed. Navigation proceeds step by step, through the layers of structure.
Deeply Nested Structures
Nesting can go as deep as the information demands:
const company = {
name: "TechCorp",
employees: [
{
name: "Alice",
role: "Engineer",
skills: ["Python", "JavaScript", "SQL"]
},
{
name: "Bob",
role: "Designer",
skills: ["Photoshop", "Illustrator"]
}
]
};
This is an object containing an array of objects, each of which contains an array. The structure mirrors the complexity of the information it represents.
Access Alice’s first skill:
console.log(company.employees[0].skills[0]); // Python
Navigation proceeds step by step: retrieve the employees array, retrieve the first employee, retrieve their skills array, retrieve the first skill. Each dot or bracket opens a door to the next layer.
This starts to look like Russian nesting dolls. And like nesting dolls, the more layers you have, the harder it becomes to track what’s inside what. Eventually, custom classes become useful for giving structure and names to these nested layers. But objects and arrays will carry you surprisingly far.
Building Something Real
Immutability: Data That Cannot Change
Here’s a philosophical question that quickly becomes practical: should data be changeable?
Arrays and objects are mutable: they may be modified after creation. But sometimes mutability is dangerous. What if multiple parts of a program reference the same array, and one of them changes it? Suddenly everyone sees different data than they expected, like a shared shopping list where someone’s been quietly crossing things off, and debugging becomes an exercise in asking “who changed this, and when?”
Immutable data cannot be changed after creation. JavaScript doesn’t have a dedicated immutable type the way Python has tuples — arrays and objects are mutable by default, full stop. What JavaScript offers instead is Object.freeze(), which takes an existing array or object and locks it: attempts to change, add, or remove its contents are silently ignored (or throw a TypeError, in strict mode), while the original values stay exactly as they were. It’s less a separate data type and more a promise extracted from an ordinary one. If you need different values, you create a new structure rather than modifying the old one.
Think of immutability as the difference between a printed book and a whiteboard. A book’s content is fixed, so everyone who reads it sees the same thing. A whiteboard can be erased and rewritten, which is flexible, but you can’t trust that what you saw five minutes ago is still there now.
We’ll revisit immutability in more depth in the appendices.
JSON: The Universal Language of Data
When programs must share data (between a web browser and a server, between a JavaScript program and a Python program, between systems across the internet), they require a common format. A lingua franca of data.
JSON (JavaScript Object Notation) has become that format. The name is not a coincidence: JSON’s syntax is JavaScript’s own object and array syntax, tightened up a little (keys must be quoted, no trailing commas, no functions or undefined allowed). It looks remarkably similar to the objects and arrays you’ve been writing all chapter:
{
"name": "Alice",
"age": 30,
"hobbies": ["reading", "hiking", "coding"],
"address": {
"city": "Portland",
"state": "OR"
}
}
This is just text. You can put it in a file, transmit it over a network, or store it in a database. Any programming language can read and write it. It’s the Esperanto of computing, except people actually use it.
// Converting a JS value to JSON
const data = { name: "Alice", age: 30 };
const jsonString = JSON.stringify(data);
console.log(jsonString); // {"name":"Alice","age":30}
// Converting JSON back to a JS value
const parsed = JSON.parse('{"name": "Bob", "age": 25}');
console.log(parsed.name); // Bob
JSON is how data travels. Web APIs speak JSON. Configuration files use JSON. When someone says “send the data as JSON,” this is what they mean.
Real-World Data Modeling
Looking Ahead
Data structures are foundational. Everything constructed in programming rests on how information is organised, the way a house you’ll live in for years rests on a foundation nobody ever photographs.
As programs grow more complex, more specialised structures emerge:
- Sets (collections where each item appears only once)
- Fixed-length tuples (not part of JavaScript itself — arrays are arrays — but you’ll meet typed tuples once TypeScript enters the picture)
- Custom classes (data structures of your own design with specific behaviours)
- Trees and graphs (hierarchical and networked relationships)
But at the core, it is all variations on the same theme: organising information in a way that makes questions easy to answer. The structure serves the inquiry.
For now, arrays and objects cover most of what you’ll need. They’re the bread and butter of organizing information. Master the two of them, and a surprising amount of the world turns out to be, underneath, an array of objects in a trench coat.
But a truth remains: programs don’t always work. Code has bugs: code you write, code AI writes, code anyone writes. The next chapter is about what happens when things go wrong, and the surprisingly systematic art of figuring out why.
Next: When programs break, and the art of finding out why.