0 / 91
Week 3 · Day 20 of 91

Objects and data modeling

JavaScript Foundations I

Objective

Group related properties into domain records.

Variables are measured signals, functions are reusable circuit blocks, and control flow determines which path becomes active.

  • object literals
  • property access
  • methods versus data

Why this matters

Yesterday's report kept names and stock in two arrays lined up by index. It worked, and it is fragile: insert one name without inserting a matching count and every stock[i] after it is silently wrong. Nothing tells you.

Today you fix that properly. An object groups related named properties into one value, so a component's id, name, value, unit, and quantity travel together and cannot drift apart. This is called data modelling, and the shapes you choose today are the shapes your database tables and API responses will have in Week 6 and Week 7.

Object literals

You write an object with curly braces, and inside it key: value pairs separated by commas.

const resistor = {
  id: "R-220",
  name: "Resistor 220",
  category: "resistor",
  value: 220,
  unit: "ohm",
  quantity: 42,
};

Each key: value pair is a property. The key (also called the property name) is on the left, written without quotes; the value on the right is any value you like — string, number, boolean, array, or another object. The trailing comma after the last property is legal and normal; it keeps future diffs small.

Note what value: 220 and unit: "ohm" do together. 220 alone is ambiguous — ohms? nanofarads? Storing the unit as its own property is a modelling decision that prevents the exact mistake Day 16 warned about.

An object is a component with a datasheet

An array is a numbered terminal strip; an object is a part with labelled pins. You do not ask for "pin 3" of an op-amp, you ask for V+ — the name is the identity, and the order the pins appear in the datasheet is irrelevant. That is why an object has no indexes: every field is reached by name.

Reading and changing properties

There are two ways to reach a property.

Dot notation is what you will use almost always:

console.log(resistor.name);
console.log(resistor.supplier);
Resistor 220
undefined

Asking for a property that does not exist is not an error — you get undefined, exactly like reading past the end of an array. This is a common source of undefined appearing in output, and it usually means a typo in the key or an object missing a field.

Bracket notation takes the key as a string, which lets the key itself be a variable:

const key = "value";
console.log(resistor["unit"]);
console.log(resistor[key]);
ohm
220

Use dots when you know the key as you write the code; use brackets when the key is decided while the program runs.

Assignment updates a property, or creates it if it is new:

resistor.quantity = 40;
resistor.location = "Bin A3";
console.log(resistor.quantity, resistor.location);
40 Bin A3

resistor is const, yet this works — for the same reason as arrays yesterday. const fixes which object the name points at; it does not freeze what is inside.

The record card

An object is an index card for one part: fields printed down the left, values written beside them. You can rub out a value and write a new one, and you can add a line at the bottom. The card is still the same card.

Methods versus data

A property whose value is a function is called a method. Everything else is data.

const part = {
  id: "R-220",
  value: 220,
  unit: "ohm",
  label() {
    return `${this.value} ${this.unit}`;
  },
};

console.log(part.label());
console.log(typeof part.label, typeof part.value);
220 ohm
function number

label() { ... } is the shorthand for a method. Inside it, this refers to the object the method was called on — so this.value is 220. You call it with parentheses: part.label(). Without them you get the function itself rather than its result, which is why typeof part.label prints function.

The distinction that matters: data is what the thing is; a method is something the thing can do. Keep stored records mostly data. Once records are only data, they can be saved to a file, sent over the network, or written to a database — none of which is possible with a function inside. That is why the deliverable today is plain data objects.

One minute

Run console.log(JSON.stringify(part)). You get {"id":"R-220","value":220,"unit":"ohm"} — the method vanished. Functions cannot cross the wire. You will meet JSON properly on Day 27.

An array of objects

Arrays and objects combine into the single most common shape in web development: a list of records.

const components = [
  { id: "R-220", name: "Resistor 220", category: "resistor", value: 220, unit: "ohm", quantity: 42 },
  { id: "R-330", name: "Resistor 330", category: "resistor", value: 330, unit: "ohm", quantity: 8 },
  { id: "C-100n", name: "Capacitor 100n", category: "capacitor", value: 100, unit: "nF", quantity: 120 },
];

console.log(components.length);
console.log(components[1].name);
3
Resistor 330

components[1] picks the object; .name reads inside it. You chain the two accessors.

Every object here has the same six keys in the same order — a consistent shape. That consistency is what makes a loop over the list safe: c.quantity works for every item, because every item has it. One object missing quantity gives undefined, and total += undefined makes NaN.

Walkthrough

Create components.js, using the array above and yesterday's for...of loop.

let total = 0;
const lowStock = [];

for (const c of components) {
  total += c.quantity;
  if (c.quantity < 10) {
    lowStock.push(c.id);
  }
}

console.log("Total units:", total);
console.log("Low stock:", lowStock);

for (const c of components) {
  console.log(`${c.id}  ${c.value} ${c.unit}  qty ${c.quantity}`);
}

Run node components.js:

Total units: 170
Low stock: [ 'R-330' ]
R-220  220 ohm  qty 42
R-330  330 ohm  qty 8
C-100n  100 nF  qty 120

Compare this with yesterday. There is one array, not two; the loop variable c carries the whole record, so c.value and c.unit are guaranteed to belong to the same component. Adding a field means editing one place. Nothing can drift out of alignment because there is no alignment to maintain.

Checkpoint

Say what components[0].unit and components[0]["unit"] each evaluate to, and why components[0].units is undefined. (Both are "ohm"; the third is a typo'd key, and missing keys return undefined rather than erroring.)

Your turn

Deliverable: a components array containing consistent object shapes.

  1. In js-basics/, create components.js with an array of five component objects. Every object gets exactly these keys, spelled identically: id, name, category, value, unit, quantity.
  2. Mix categories — at least one resistor, one capacitor, one LED — and give at least one item a quantity below 10.
  3. Log components.length and components[0].name to confirm the structure.
  4. Read one property with dot notation and the same one with bracket notation. Confirm identical output.
  5. Loop with for...of to compute total quantity and collect the ids of low-stock items, then print both.
  6. Print a one-line summary per component with a template literal, including the unit.
  7. Deliberately delete the unit key from one object and rerun. Find the undefined in your output, then put it back. That is what an inconsistent shape looks like from the outside.

Reviewer mode — once your five objects are written

"Inspect these objects for inconsistent property names, mixed units, and missing identifiers." A useful review returns specific, actionable findings with evidence: which object, which key, what breaks. Praise or a wholesale rewrite is not a review. Check each finding against your own file before changing anything.

Common pitfalls

  • Inconsistent keys across records. qty in one object and quantity in the next means c.quantity is undefined for half your data. Pick one spelling and keep it.
  • Numbers carrying units in the value. value: "220 ohm" is a string, so arithmetic breaks. Keep value numeric and unit separate.
  • Confusing arrays and objects. components[0] is by position; component.name is by name. components.name and component[0] are both undefined.
  • Forgetting the parentheses on a method. part.label gives the function; part.label() gives the result.

Verify it yourself

Open today's reference, MDN's Dynamic scripting with JavaScript, and find its introduction to objects.

  1. MDN shows objects nested inside other objects. Write down how you would read a property two levels deep, using dots.
  2. Find MDN's explanation of this inside a method. Does it agree it refers to the object the method was called on?

Write both answers as comments at the bottom of components.js.

The hour

  1. 0–5 min Recall

    Without notes, state yesterday’s main idea and one unresolved question.

  2. 5–20 min Learn

    Read only the listed concept notes and official reference sections needed today.

  3. 20–48 min Build

    Model electronic components as objects with id, name, category, value, unit, and quantity.

  4. 48–55 min Explain and verify

    Run the result, inspect evidence, and explain the data/control flow in your own words.

  5. 55–60 min Quiz and commit

    Complete the quiz, record one lesson, and commit the verified change when applicable.

What to hand in

Deliverable

A components array containing consistent object shapes.

Working with AI today

AI as skeptical reviewer

Provide existing work and ask for concrete defects, risks, missing tests, and unsupported assumptions—not praise.

Inspect these objects for inconsistent property names, mixed units, and missing identifiers.

References

End-of-day quiz

Q1 What is an object useful for?
Q2 Which result best proves today’s work is complete?
Q3 What should an AI code review primarily produce?

Explain-back gate

Pass the quiz above to unlock completion.

Quiz + explain-back checks required.