Step 4
Step 4 — JavaScript basics
40 min
Step 4 — JavaScript basics
The language that moves the browser. Four things — variables, functions, events, async — cover 90%.
1. Three variable keywords
const name = "Codingstairs"; // won't change (most cases)
let count = 0; // will change
// var — legacy, avoid in new code
Rule: const first, let only when reassignment is needed.
2. Types
typeof "hello" // "string"
typeof 42 // "number"
typeof true // "boolean"
typeof undefined // "undefined"
typeof null // "object" (historical bug)
typeof Symbol() // "symbol"
typeof 42n // "bigint"
typeof {} // "object"
typeof [] // "object" (use Array.isArray)
undefined = not assigned; null = explicitly empty.
3. Functions — three forms
function add(a, b) { return a + b; }
const subtract = function(a, b) { return a - b; };
const multiply = (a, b) => a * b;
const square = (x) => { const r = x * x; return r; };
Arrow functions don't bind this — handy for callbacks, wrong for constructors.
4. Objects and arrays
const user = {
name: "Alice", age: 25,
greet() { return `hi, ${this.name}`; },
};
user.name; user["name"]; user.greet();
const fruits = ["apple", "banana", "cherry"];
fruits[0];
fruits.length;
fruits.push("watermelon");
fruits.map(f => f.length); // [5, 6, 6, 10]
5. Events
<button id="hi">Click me</button>
<input id="name" placeholder="name">
<script>
const btn = document.getElementById("hi");
const name = document.getElementById("name");
btn.addEventListener("click", () => {
alert(`Hi, ${name.value}!`);
});
name.addEventListener("input", (e) => {
console.log("value:", e.target.value);
});
</script>
Find → listen → react.
6. Async — Promise · async/await
fetch("/api/users")
.then(res => res.json())
.then(users => console.log(users))
.catch(err => console.error(err));
async function loadUsers() {
try {
const res = await fetch("/api/users");
const users = await res.json();
console.log(users);
} catch (err) {
console.error(err);
}
}
loadUsers();
async functions always return a Promise. await only inside async.
7. Modern syntax
// Destructuring
const { name, age } = user;
const [first, second] = fruits;
// Spread
const newUser = { ...user, email: "a@b.com" };
const extended = [...fruits, "strawberry"];
// Optional chaining
const city = user?.address?.city;
// Nullish coalescing
const displayName = user.nickname ?? "guest";
// Template literals
const msg = `hi ${name}, age ${age}`;
8. Array methods
const nums = [1, 2, 3, 4, 5];
nums.map(n => n * 2);
nums.filter(n => n > 2);
nums.reduce((s, n) => s + n, 0);
nums.find(n => n > 3);
nums.some(n => n > 4);
nums.every(n => n > 0);
nums.forEach(n => console.log(n));
Replace most loops with these.
9. JSON
const str = JSON.stringify({ name: "Alice", age: 25 });
const obj = JSON.parse('{"name":"Alice","age":25}');
10. Try it — tiny todo
<input id="task" placeholder="task">
<button id="add">add</button>
<ul id="list"></ul>
<script>
const task = document.getElementById("task");
const list = document.getElementById("list");
document.getElementById("add").addEventListener("click", () => {
if (!task.value.trim()) return;
const li = document.createElement("li");
li.textContent = task.value;
li.addEventListener("click", () => li.remove());
list.appendChild(li);
task.value = "";
});
</script>
11. Gotchas
==vs===— always===thisin arrow vs regular — different rules- Callback hell — use Promise chain or async/await
- Global leaks — always
const/let - Unhandled rejection — wrap
awaitin try/catch
12. TypeScript next
TS adds types on top — autocomplete, early errors, safer refactor. Modern frontend is almost all TS.
Deeper
Next
Step 5 — React 19 writes the same interactions more elegantly.