Describe a thing with key-value pairs
const person = {
name: "Alice",
age: 25,
city: "Taipei"
}
person.name // "Alice"
person.age // 25
person.city // "Taipei"
{ }
key: value
.key
Think of it like filling out a form:
| Field | Value |
|---|---|
| Name | Alice |
| Age | 25 |
| City | Taipei |
const form = {
name: "Alice",
age: 25,
city: "Taipei"
}
Real data is usually a list of things:
const menu = [
{ name: "Coffee", price: 50 },
{ name: "Tea", price: 40 },
{ name: "Juice", price: 60 }
]
menu[0].name // "Coffee"
menu[0].price // 50
menu[1].name // "Tea"
Extract one field from every item:
const menu = [
{ name: "Coffee", price: 50 },
{ name: "Tea", price: 40 },
{ name: "Juice", price: 60 }
]
menu.map(item => item.name)
// ["Coffee", "Tea", "Juice"]
menu.map(item => item.price)
// [50, 40, 60]
{ key: value } — describe a thing.key
.map() works on arrays of objects tooPick what you want from a list
Keep only the items that pass a test:
[1, 2, 3, 4, 5].filter(x => x > 3)
// [4, 5]
[10, 20, 30, 40].filter(x => x >= 25)
// [30, 40]
true → keep itfalse → remove itUse ch02 logic inside filter:
const ages = [12, 25, 8, 30, 15, 45]
ages.filter(age => age >= 18)
// [25, 30, 45]
ages.filter(age => age < 18)
// [12, 8, 15]
const menu = [
{ name: "Coffee", price: 50 },
{ name: "Cake", price: 120 },
{ name: "Tea", price: 40 },
{ name: "Steak", price: 350 }
]
menu.filter(item => item.price <= 100)
// [{ name: "Coffee", price: 50 }, { name: "Tea", price: 40 }]
Chain them:
const menu = [
{ name: "Coffee", price: 50 },
{ name: "Cake", price: 120 },
{ name: "Tea", price: 40 },
{ name: "Steak", price: 350 }
]
// names of items under 100
menu
.filter(item => item.price <= 100)
.map(item => item.name)
// ["Coffee", "Tea"]
.filter(fn) — keep items where fn returns true.map() for data pipelinesMake elements sit side by side or stack nicely
By default, every <div> takes a full row:
<div>A</div>
<div>B</div>
<div>C</div>
They stack vertically. What if we want them side by side?
Add display: flex to the parent:
<div style="display: flex; gap: 10px;">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
Now A, B, C sit side by side!
.container {
display: flex;
flex-direction: row; /* side by side (default) */
}
.container {
display: flex;
flex-direction: column; /* stacked vertically */
}
body {
display: flex;
justify-content: center; /* horizontal center */
align-items: center; /* vertical center */
height: 100vh; /* full screen height */
}
This is how we centered the counter in ch07!
const box = document.createElement("div")
box.style.display = "flex"
box.style.gap = "10px"
;["A", "B", "C"].forEach(text => {
const item = document.createElement("div")
item.textContent = text
item.style.padding = "20px"
item.style.border = "1px solid white"
box.appendChild(item)
})
document.body.appendChild(box)
display: flex — make children sit in a rowflex-direction: column — stack verticallyjustify-content: center — center on main axisalign-items: center — center on cross axisgap — spacing between itemsCombine arrays, objects, map, filter, and flexbox
A list of cards from data, with a filter:
[Show All] [Under 100] [Over 100]
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Coffee │ │ Tea │ │ Cake │
│ $50 │ │ $40 │ │ $120 │
└──────────┘ └──────────┘ └──────────┘
const menu = [
{ name: "Coffee", price: 50 },
{ name: "Tea", price: 40 },
{ name: "Cake", price: 120 },
{ name: "Juice", price: 60 },
{ name: "Steak", price: 350 },
{ name: "Salad", price: 80 }
]
A function that creates one card — ch01 style:
const Card = item => {
const div = document.createElement("div")
div.className = "card"
div.innerHTML = "<h3>" + item.name + "</h3>"
+ "<p>$" + item.price + "</p>"
return div
}
const container = document.querySelector("#cards")
const render = items => {
container.innerHTML = ""
items
.map(Card)
.forEach(card => container.appendChild(card))
}
render(menu)
document.querySelector("#all").addEventListener("click",
() => render(menu))
document.querySelector("#cheap").addEventListener("click",
() => render(menu.filter(item => item.price <= 100)))
document.querySelector("#expensive").addEventListener("click",
() => render(menu.filter(item => item.price > 100)))
<!DOCTYPE html>
<html>
<head>
<title>Menu</title>
<style>
body {
background: #1a1a2e; color: #eee;
font-family: sans-serif; padding: 20px;
}
.filters { margin-bottom: 20px; }
.filters button {
padding: 8px 16px; margin: 4px;
border: 1px solid #eee; background: none;
color: #eee; cursor: pointer; border-radius: 4px;
}
.filters button:hover { background: #333; }
#cards { display: flex; flex-wrap: wrap; gap: 10px; }
.card {
border: 1px solid #444; border-radius: 8px;
padding: 16px; min-width: 120px;
}
.card h3 { margin: 0 0 8px 0; }
.card p { margin: 0; color: #aaa; }
</style>
</head>
<body>
<h1>Menu</h1>
<div class="filters">
<button id="all">All</button>
<button id="cheap">Under $100</button>
<button id="expensive">Over $100</button>
</div>
<div id="cards"></div>
<script>
const menu = [
{ name: "Coffee", price: 50 },
{ name: "Tea", price: 40 },
{ name: "Cake", price: 120 },
{ name: "Juice", price: 60 },
{ name: "Steak", price: 350 },
{ name: "Salad", price: 80 }
]
const Card = item => {
const div = document.createElement("div")
div.className = "card"
div.innerHTML = "<h3>" + item.name + "</h3>"
+ "<p>$" + item.price + "</p>"
return div
}
const container = document.querySelector("#cards")
const render = items => {
container.innerHTML = ""
items.map(Card).forEach(c => container.appendChild(c))
}
document.querySelector("#all").addEventListener("click",
() => render(menu))
document.querySelector("#cheap").addEventListener("click",
() => render(menu.filter(i => i.price <= 100)))
document.querySelector("#expensive").addEventListener("click",
() => render(menu.filter(i => i.price > 100)))
render(menu)
</script>
</body>
</html>
| Chapter | What |
|---|---|
| ch01 | Functions — Card, render
|
| ch02 | Logic — price <= 100
|
| ch04 | CSS — styling cards |
| ch05 | DOM — createElement, appendChild |
| ch06 | Events — button clicks |
| ch08 | Arrays — list of menu items |
| ch09 | Objects — { name, price }
|
| ch10 | Filter — filter by price |
| ch11 | Flexbox — card layout |