Objects · The DOM · Events · Asynchronous JavaScript
Master JavaScript's most-used data structure: objects. Learn destructuring, the shorthand syntax, Object.keys / values / entries, and immutable updates with spread. Reach into the page from JavaScript. Select elements, change content, toggle classes, and create new nodes — without external libraries. Respond to user actions: handle clicks, form input, submissions, and delegate events for dynamic lists. Stop default behaviors when needed. Stop blocking the UI. Use Promises, async/await, and fetch to talk to APIs cleanly — with proper error handling and loading states.
What you'll learn
- 1Create objects with literal and shorthand syntax
- 2Destructure values out of objects (and arrays)
- 3Iterate with Object.keys / values / entries
- 4Update objects immutably with spread
- 5Select elements with querySelector / All
- 6Read and write text and HTML safely
- 7Toggle classes for state-driven styling
- 8Create, append, and remove DOM nodes
- 9Attach handlers with addEventListener (not onclick)
- 10Read event.target and event.currentTarget correctly
- 11Use event delegation for dynamic content
- 12Cancel default behavior with preventDefault
- 13Explain microtask queue and why async is non-blocking
- 14Consume Promises with .then or async/await
- 15Use try/catch for async error handling
- 16Run requests in parallel with Promise.all
Objects
Master JavaScript's most-used data structure: objects. Learn destructuring, the shorthand syntax, Object.keys / values / entries, and immutable updates with spread.
1. Object Basics
const name = "Alice";
const age = 30;
// Shorthand: key omitted when name matches
const user = { name, age, greet() { return `hi, ${this.name}`; } };
console.log(user.name); // dot access
console.log(user["age"]); // bracket access
user.email = "a@example.com"; // add a property
delete user.age; // remove2. Destructuring
const user = { name: "Alice", age: 30, city: "Seoul" };
const { name, age } = user;
console.log(name, age); // Alice 30
// Rename + default
const { name: fullName, role = "user" } = user;
// Array destructuring
const [first, second, ...rest] = [1, 2, 3, 4, 5];3. Iterate Over Objects
Object.keys(user); // ["name", "age", "city"]
Object.values(user); // ["Alice", 30, "Seoul"]
Object.entries(user); // [["name","Alice"], ["age",30], ["city","Seoul"]]
for (const [key, value] of Object.entries(user)) {
console.log(`${key}: ${value}`);
}4. Immutable Update
const updated = { ...user, age: 31 }; // new object, original untouched
const { city, ...withoutCity } = user; // remove a key
const merged = { ...defaults, ...overrides };The DOM
Reach into the page from JavaScript. Select elements, change content, toggle classes, and create new nodes — without external libraries.
1. Selecting
const title = document.querySelector("h1");
const items = document.querySelectorAll(".item");
const byId = document.getElementById("main");
items.forEach(el => console.log(el.textContent));2. Reading & Writing
title.textContent = "New title"; // safe text
title.innerHTML = "<strong>HTML</strong>"; // parses as HTML
const input = document.querySelector("#name");
input.value = "Alice"; // form value
title.setAttribute("id", "main-title");Prefer textContent over innerHTML. innerHTML with user data is an XSS risk — see security lectures.
3. Classes & Styles
el.classList.add("active");
el.classList.remove("active");
el.classList.toggle("open");
el.classList.contains("active");
el.style.backgroundColor = "crimson"; // direct inline (avoid for state — use classes)
el.style.setProperty("--accent", "#22c55e");4. Create / Append / Remove
const li = document.createElement("li");
li.textContent = "New task";
li.classList.add("task");
document.querySelector("ul").appendChild(li);
li.remove(); // remove from DOM
ul.replaceChildren(); // clear all childrenEvents
Respond to user actions: handle clicks, form input, submissions, and delegate events for dynamic lists. Stop default behaviors when needed.
1. addEventListener
const btn = document.querySelector("#go");
function handleClick(e) {
console.log("clicked", e.currentTarget);
}
btn.addEventListener("click", handleClick);
btn.removeEventListener("click", handleClick); // detachaddEventListener supports multiple listeners on the same element and lets you remove them later — onclick does not.
2. Form Input
const form = document.querySelector("#signup");
form.addEventListener("submit", (e) => {
e.preventDefault(); // do NOT navigate to action URL
const data = new FormData(form);
console.log(Object.fromEntries(data));
});
const input = document.querySelector("#search");
input.addEventListener("input", (e) => {
console.log(e.target.value);
});3. Event Delegation
Instead of attaching a listener to every <li>, attach one to the parent <ul> and inspect event.target.
document.querySelector("#tasks").addEventListener("click", (e) => {
const li = e.target.closest("li");
if (!li) return;
if (e.target.matches(".delete")) {
li.remove();
} else if (e.target.matches(".toggle")) {
li.classList.toggle("done");
}
});Delegation handles items added later automatically — perfect for dynamic lists.
4. Common Events
| Event | Fires when |
|---|---|
| click | Element is clicked |
| input | Form field value changes |
| change | Form field commits (blur / select change) |
| submit | Form is submitted |
| keydown / keyup | Keyboard interaction |
| mouseenter / mouseleave | Mouse enters/leaves (no bubbling) |
| focus / blur | Focus changes |
Asynchronous JavaScript
Stop blocking the UI. Use Promises, async/await, and fetch to talk to APIs cleanly — with proper error handling and loading states.
1. Why Async?
Network calls, timers, and file reads take time. If JavaScript waited synchronously, the page would freeze. Async lets you schedule "do this when it is ready" and continue.
2. Promises
fetch("https://api.example.com/users")
.then(res => res.json())
.then(users => console.log(users))
.catch(err => console.error(err))
.finally(() => hideLoader());3. async/await (Preferred)
async function loadUsers() {
try {
const res = await fetch("https://api.example.com/users");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const users = await res.json();
render(users);
} catch (err) {
showError(err.message);
} finally {
hideLoader();
}
}await only works inside async functions. Top-level await is allowed in ES modules.
4. Parallel Requests
const [users, posts, comments] = await Promise.all([
fetch("/api/users").then(r => r.json()),
fetch("/api/posts").then(r => r.json()),
fetch("/api/comments").then(r => r.json()),
]);
// All three run concurrently, total time = slowest onePromise.all rejects if any of them fails. Use Promise.allSettled if you want partial success.
5. fetch Options
const res = await fetch("/api/posts", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: "Hello" }),
signal: AbortSignal.timeout(5000), // 5s timeout
});All lecture materials and example code are openly available on GitHub.
View on GitHub ↗Comments 0
No comments yet. Be the first.
Only members can comment.
Comments with ads, abuse, personal information or illegal content are hidden or removed. Comments are shown with your nickname. Privacy Policy