ch01 Functions

ch01 — Functions

We start from equations, not syntax

What is F12 Console?

Try it now:

1 + 1

You should see 2.

Equation = Function

Everyone already knows this:

f(x) = x + 1

This is a function. That’s it.

Your First Code

f(x) = x + 1 in JavaScript:

const f = x => x + 1

f(1)
f(10)
f(100)

Paste it in F12 Console. You just ran your first function.

Another Function

double(x) = x * 2

const double = x => x * 2

double(3)
double(10)
double(0)

The pattern is always the same:

name(input) = ruleconst name = input => rule

Try More

const square = x => x * x
square(3)
square(5)
const half = x => x / 2
half(10)
half(100)

Make your own! Change the rule, see what happens.

Same Input = Same Output

const double = x => x * 2
double(5)
double(5)
double(5)

Always 10. Every time. No surprises.

Combine Functions

Build bigger rules from smaller rules:

const add1 = x => x + 1
const double = x => x * 2

const add1ThenDouble = x => double(add1(x))

add1ThenDouble(3)
// add1(3) = 4, double(4) = 8

Summary


ch02 Logic

ch02 — Logic

In ch01 we learned: input → rule → output

Now we learn how to make decisions

If It Rains, the Ground Gets Wet

We already use logic in daily life:

This is if P → Q

If in JavaScript

const weather = "rain"

if (weather === "rain") {
  console.log("Bring an umbrella")
}

If…Else

What if it’s NOT raining?

const weather = "sunny"

if (weather === "rain") {
  console.log("Bring an umbrella")
} else {
  console.log("Enjoy the sunshine")
}

True and False

Conditions are either true or false:

3 > 1    // true
5 < 2    // false
3 === 3  // true
3 === 5  // false
Symbol Meaning
=== is equal to
!== is not equal to
> greater than
< less than
>= greater or equal
<= less or equal

If…Else If…Else

Multiple conditions:

const temp = 35

if (temp > 30) {
  console.log("Very hot")
} else if (temp > 20) {
  console.log("Nice weather")
} else {
  console.log("Bring a jacket")
}

Checks from top to bottom. Runs the first one that’s true.

Logic Inside Functions

Put logic inside a function — still input → output:

const advice = temp => {
  if (temp > 30) {
    return "Drink water"
  } else if (temp > 20) {
    return "Nice weather"
  } else {
    return "Bring a jacket"
  }
}

advice(35)
advice(25)
advice(10)

And, Or, Not

Combine conditions:

// AND: both must be true
if (age >= 18 && hasTicket) {
  console.log("You can enter")
}

// OR: at least one true
if (age < 12 || age >= 65) {
  console.log("Discount")
}

// NOT: flip
if (!hasTicket) {
  console.log("Buy a ticket")
}
Symbol Meaning
&& AND
\|\| OR
! NOT

Real Example: Restaurant

const getPrice = (item, isMember) => {
  if (item === "coffee") {
    if (isMember) {
      return 40
    } else {
      return 50
    }
  } else if (item === "tea") {
    if (isMember) {
      return 30
    } else {
      return 40
    }
  } else {
    return 0
  }
}

getPrice("coffee", true)   // 40
getPrice("coffee", false)  // 50

Summary


ch03 HTML

ch03 — HTML

Now we learn what a web page actually is

What is HTML?

HTML is the structure of every web page:

<html>
  <head>
    <title>My Page</title>
  </head>
  <body>
    <h1>Hello</h1>
    <p>This is a paragraph</p>
  </body>
</html>

Common Elements

Element What it does
<h1> to <h6> Headings (h1 biggest)
<p> Paragraph
<div> Container box
<span> Inline container
<a href="..."> Link
<img src="..."> Image
<button> Button
<input> Text input
<ul> / <li> List

Boxes Inside Boxes

HTML is layers of boxes:

html
├── head
│   └── title
└── body
    ├── h1
    ├── p
    └── div
        └── button

Create Your First HTML File

Create a file called my-page.html:

<!DOCTYPE html>
<html>
<head>
  <title>My Page</title>
</head>
<body>
  <h1>Hello World</h1>
  <p>This is my first web page!</p>
  <button>Click me</button>
</body>
</html>

Open it in your browser. You made a web page!

Summary


ch04 CSS Basics

ch04 — CSS Basics

HTML is the structure. CSS makes it look good.

What is CSS?

h1 {
  color: red;
  font-size: 32px;
}

Add CSS to HTML

Add <style> in <head>:

<head>
  <title>My Page</title>
  <style>
    h1 { color: red; }
    p { font-size: 20px; }
    body {
      background: #1a1a2e;
      color: #eee;
      font-family: sans-serif;
    }
  </style>
</head>

Colors

color: red;              /* named */
color: #ff0000;          /* hex */
color: rgb(255, 0, 0);   /* rgb */

Common: red, blue, green, white, black, gray, orange

Try in F12:

document.querySelector("h1").style.color = "red"

Box Model

Every element is a box:

┌──────── margin ────────┐
│ ┌───── border ───────┐ │
│ │ ┌── padding ─────┐ │ │
│ │ │    content      │ │ │
│ │ └────────────────┘ │ │
│ └────────────────────┘ │
└────────────────────────┘
div {
  padding: 10px;
  border: 1px solid white;
  margin: 20px;
}

Style a Button

button {
  font-size: 20px;
  padding: 10px 24px;
  border: 1px solid #eee;
  background: none;
  color: #eee;
  cursor: pointer;
  border-radius: 8px;
}

Copy this into your <style>. The button looks much better now.

Summary


ch05 DOM

ch05 — DOM

JavaScript can read and change any element on the page

Select an Element

document.querySelector("h1")
document.querySelector("p")
document.querySelector("button")

Change Text

const h1 = document.querySelector("h1")
h1.textContent = "I changed this!"

The page updates instantly. No reload needed.

Change Style

const h1 = document.querySelector("h1")
h1.style.color = "red"
h1.style.fontSize = "50px"

This is the same as CSS, but controlled by JavaScript.

Create New Elements

const p = document.createElement("p")
p.textContent = "I was created by JavaScript!"
document.body.appendChild(p)

Remove Elements

document.querySelector("h1").remove()

Try it on any website — remove things you don’t like!

Summary


ch06 Events

ch06 — Events

Make the page respond to clicks and actions

Click Event

const btn = document.querySelector("button")

btn.addEventListener("click", () => {
  alert("You clicked!")
})

Click Counter

Create a button that counts clicks:

const btn = document.querySelector("button")
let count = 0

btn.addEventListener("click", () => {
  count = count + 1
  btn.textContent = "Clicked: " + count
})

Paste in F12 Console. The button now counts!

Change Content on Click

const btn = document.querySelector("button")
const h1 = document.querySelector("h1")

btn.addEventListener("click", () => {
  h1.textContent = "Button was clicked!"
  h1.style.color = "green"
})

Functions from ch01 + DOM from ch05 + Events = interactive page!

Common Events

Event When
click User clicks
mouseover Mouse enters
mouseout Mouse leaves
keydown Key pressed
input Input value changes

Summary


ch07 Project: Counter

ch07 — Project: Counter

Combine everything into one file!

What We’re Building

┌─────────────────────┐
│                     │
│        42           │
│                     │
│   [ - ]    [ + ]    │
│                     │
│   [ Reset ]         │
│                     │
└─────────────────────┘

Step 1: HTML

Create counter.html:

<!DOCTYPE html>
<html>
<head>
  <title>Counter</title>
</head>
<body>
  <h1 id="count">0</h1>
  <button id="dec">-</button>
  <button id="inc">+</button>
  <button id="reset">Reset</button>
</body>
</html>

Open in browser. You see 0 and three buttons.

Step 2: JavaScript

Add <script> before </body>:

<script>
  let count = 0
  const display = document.querySelector("#count")

  document.querySelector("#inc").addEventListener("click", () => {
    count = count + 1
    display.textContent = count
  })

  document.querySelector("#dec").addEventListener("click", () => {
    count = count - 1
    display.textContent = count
  })

  document.querySelector("#reset").addEventListener("click", () => {
    count = 0
    display.textContent = count
  })
</script>

The buttons work now!

Step 3: Refactor with Functions

There’s repeated code. Use a function:

<script>
  let count = 0
  const display = document.querySelector("#count")

  const update = fn => {
    count = fn(count)
    display.textContent = count
  }

  document.querySelector("#inc").addEventListener("click",
    () => update(n => n + 1))
  document.querySelector("#dec").addEventListener("click",
    () => update(n => n - 1))
  document.querySelector("#reset").addEventListener("click",
    () => update(() => 0))
</script>

update takes a function — ch01 equation style!

Step 4: Add CSS

Add <style> in <head>:

<style>
  body {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
    margin: 0;
    background: #1a1a2e;
    color: #eee;
    font-family: sans-serif;
  }
  #count { font-size: 80px; margin: 20px; }
  button {
    font-size: 24px; padding: 10px 24px; margin: 5px;
    border: 1px solid #eee; background: none; color: #eee;
    cursor: pointer; border-radius: 8px;
  }
  button:hover { background: #333; }
</style>

Step 5: Add Color with Logic

Use ch02 logic to change color:

const getColor = n => {
  if (n > 0) {
    return "green"
  } else if (n < 0) {
    return "red"
  } else {
    return "#eee"
  }
}

const update = fn => {
  count = fn(count)
  display.textContent = count
  display.style.color = getColor(count)
}

What We Used

Chapter What How
ch01 Functions n => n + 1
ch02 Logic getColor with if/else
ch03 HTML h1, button
ch04 CSS styling, flexbox
ch05 DOM querySelector, textContent
ch06 Events addEventListener click

Summary


ch08 Arrays

ch08 — Arrays

A list of things

What is an Array?

const fruits = ["Apple", "Banana", "Cherry"]
const nums = [1, 2, 3, 4, 5]
const prices = [50, 30, 40, 60]

Access Items

const fruits = ["Apple", "Banana", "Cherry"]

fruits[0]  // "Apple"   (first)
fruits[1]  // "Banana"  (second)
fruits[2]  // "Cherry"  (third)

fruits.length // 3

Map: Transform Every Item

Apply a function to every item in the list:

[1, 2, 3].map(x => x * 2)
// [2, 4, 6]

[1, 2, 3].map(x => x + 10)
// [11, 12, 13]

["apple", "banana"].map(s => s.toUpperCase())
// ["APPLE", "BANANA"]

Map: Real Example

Calculate prices with tax:

const prices = [100, 200, 50]

prices.map(p => p * 1.1)
// [110, 220, 55]

Double all scores:

const scores = [80, 90, 70]

scores.map(s => s * 2)
// [160, 180, 140]

Summary


ch09 Objects

ch09 — Objects

Describe a thing with key-value pairs

What is an Object?

const person = {
  name: "Alice",
  age: 25,
  city: "Taipei"
}

person.name // "Alice"
person.age  // 25
person.city // "Taipei"

Like a Form

Think of it like filling out a form:

Field Value
Name Alice
Age 25
City Taipei
const form = {
  name: "Alice",
  age: 25,
  city: "Taipei"
}

Arrays of Objects

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"

Map on Objects

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]

Summary


ch10 Filter

ch10 — Filter

Pick what you want from a list

What is Filter?

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]

Filter with Logic

Use 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]

Filter Objects

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 }]

Map + Filter Together

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"]

Summary


ch11 Layout

ch11 — Layout with Flexbox

Make elements sit side by side or stack nicely

The Problem

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?

Flexbox

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!

Flex Direction

.container {
  display: flex;
  flex-direction: row;    /* side by side (default) */
}

.container {
  display: flex;
  flex-direction: column; /* stacked vertically */
}

Centering

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!

Try It in F12

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)

Summary


ch12 Project: Card List

ch12 — Project: Card List

Combine arrays, objects, map, filter, and flexbox

What We’re Building

A list of cards from data, with a filter:

[Show All] [Under 100] [Over 100]

┌──────────┐ ┌──────────┐ ┌──────────┐
│ Coffee   │ │ Tea      │ │ Cake     │
│ $50      │ │ $40      │ │ $120     │
└──────────┘ └──────────┘ └──────────┘

Step 1: The Data

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 }
]

Step 2: Card Function

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
}

Step 3: Render List

const container = document.querySelector("#cards")

const render = items => {
  container.innerHTML = ""
  items
    .map(Card)
    .forEach(card => container.appendChild(card))
}

render(menu)

Step 4: Filter Buttons

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)))

Full Code

<!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>

What We Used

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

Summary


ch13 Multiple Inputs

ch13 — Multiple Inputs

Functions with more than one input

Two Inputs

const add = (x, y) => x + y

add(1, 2)   // 3
add(10, 20) // 30
const area = (w, h) => w * h

area(3, 4)  // 12
area(5, 10) // 50

Three Inputs

const volume = (w, h, d) => w * h * d

volume(2, 3, 4)  // 24
volume(10, 5, 2) // 100
const fullName = (first, middle, last) =>
  first + " " + middle + " " + last

fullName("John", "F", "Kennedy")
// "John F Kennedy"

Vectors

A vector is just an array: [x, y, z]

const dot = (a, b) =>
  a[0]*b[0] + a[1]*b[1] + a[2]*b[2]

dot([1,0,0], [0,1,0]) // 0
dot([1,0,0], [1,0,0]) // 1
const cross = (a, b) => [
  a[1]*b[2] - a[2]*b[1],
  a[2]*b[0] - a[0]*b[2],
  a[0]*b[1] - a[1]*b[0]
]

cross([1,0,0], [0,1,0]) // [0, 0, 1]

Summary


ch14 Advanced Data

ch14 — Advanced Data

More powerful ways to work with data

Reduce

Combine all items into one value:

[1, 2, 3, 4].reduce((total, x) => total + x, 0)
// 10

Reduce: More

// total price
const prices = [50, 40, 120, 60]
prices.reduce((total, p) => total + p, 0)
// 270

// find max
[3, 1, 4, 1, 5].reduce((max, x) =>
  max > x ? max : x)
// 5

Destructuring

Pull values out of an object:

const person = { name: "Alice", age: 25 }

const { name, age } = person

name // "Alice"
age  // 25

Pull values out of an array:

const [r, g, b] = [255, 128, 0]

r // 255
g // 128
b // 0

Spread

Copy and merge arrays:

const a = [1, 2, 3]
const b = [4, 5, 6]
const c = [...a, ...b]  // [1, 2, 3, 4, 5, 6]

Copy and update objects:

const person = { name: "Alice", age: 25 }
const updated = { ...person, age: 26 }
// { name: "Alice", age: 26 }

The original is never changed.

JSON

How data travels over the internet:

const data = { name: "Alice", scores: [90, 85, 92] }

JSON.stringify(data)
// '{"name":"Alice","scores":[90,85,92]}'

JSON.parse('{"name":"Bob","age":30}')
// { name: "Bob", age: 30 }

Summary


ch15 Advanced Functions

ch15 — Advanced Functions

Functions that are even more powerful

Currying

A function that returns a function:

const add = x => y => x + y

const add5 = add(5)
add5(3)  // 8
add5(10) // 15

Create specialized functions from general ones.

Currying: Practical

const multiply = x => y => x * y

const double = multiply(2)
const triple = multiply(3)

[1, 2, 3].map(double) // [2, 4, 6]
[1, 2, 3].map(triple) // [3, 6, 9]

Closures

Inner function remembers outer variables:

const counter = () => {
  let count = 0
  return () => {
    count = count + 1
    return count
  }
}

const c = counter()
c() // 1
c() // 2
c() // 3

Clamp and Lerp

const clamp = (value, min, max) =>
  Math.min(Math.max(value, min), max)

clamp(5, 0, 10)   // 5
clamp(-3, 0, 10)  // 0
clamp(99, 0, 10)  // 10
const lerp = (a, b, t) => a + (b - a) * t

lerp(0, 100, 0.5) // 50
lerp(0, 100, 0.1) // 10

Summary


ch16 Advanced CSS

ch16 — Advanced CSS

Grid

For 2D layouts:

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 10px;
}

Responsive

Change layout based on screen size:

.container { flex-direction: column; }

@media (min-width: 768px) {
  .container { flex-direction: row; }
}
Name Width
Mobile < 768px
Tablet 768 - 1024px
Desktop > 1024px

Transitions

Smooth animations:

button {
  background: blue;
  transition: background 0.3s;
}
button:hover {
  background: red;
}

CSS Variables

:root {
  --primary: #3498db;
  --bg: #1a1a2e;
}
h1 { color: var(--primary); }
body { background: var(--bg); }

Change one variable, everything updates.

Summary