After this lesson, you will be able to: Write JavaScript that uses variables, functions, conditionals, and loops to solve small problems in the browser.
JavaScript adds behavior to a webpage. The core language has a lot in common with Python, variables, functions, conditionals, loops, but with different syntax and a few quirks. This lesson focuses on the core language; next lesson we'll connect it to actual webpages.
Use const by default. Use let only when you need to reassign. Don't use var.
const name = "Alex"; // can't be reassignedlet score = 0; // can be reassignedscore = score + 10;// Types are inferred, no need to declare themconst age = 17; // numberconst isStudent = true; // booleanconst hobbies = ["code"]; // array
Modern code uses arrow functions for short callbacks and named functions for everything else.
// Named function declarationfunction greet(name) {return "Hello, " + name;}// Arrow function (short, modern)const greet2 = (name) => "Hello, " + name;// Multi-line arrow functionconst calcTotal = (price, taxRate = 0.08) => {const tax = price * taxRate;return price + tax;};
Same idea as Python, different syntax. Note the curly braces and parentheses.
const score = 87;let grade;if (score >= 90) {grade = "A";} else if (score >= 80) {grade = "B";} else {grade = "C or below";}// Loop through an arrayconst names = ["Alex", "Jordan", "Sam"];for (const name of names) {console.log(name);}// Or with .forEachnames.forEach((name) => console.log(name));
Template literals (backticks) are the modern way to build strings.
const name = "Alex";const age = 17;// Old way, concatenationconst msg1 = "Hi " + name + ", you are " + age;// New way, template literalsconst msg2 = `Hi ${name}, you are ${age}`;// String methodsconsole.log(name.toUpperCase()); // "ALEX"console.log(name.length); // 4console.log(" hi ".trim()); // "hi"
The next five features arrived in ES2015 onward and are now the standard syntax every team uses in 2025. Skipping them is what makes code feel dated. The code block below shows them all with real comments. You won't memorize these on first read; what matters is recognizing the pattern when you see it.
Each pattern below replaces a longer, older form. Read the comments first, then run it mentally before moving on.
// Destructuring: pull values out of objects/arrays by name/positionconst user = { name: "Alex", age: 17, role: "student" };const { name, role } = user;console.log(name, role); // "Alex" "student"const nums = [10, 20, 30];const [first, second] = nums;console.log(first, second); // 10 20// Spread (...): copy or expand iterablesconst extra = [40, 50];const combined = [...nums, ...extra]; // [10, 20, 30, 40, 50]const clone = { ...user, role: "tutor" }; // overrides role on the copy// Rest (...): collect remaining args into an arrayfunction sum(...values) {return values.reduce((acc, n) => acc + n, 0);}console.log(sum(1, 2, 3, 4)); // 10// Optional chaining (?.): safely read nested propertiesconst maybeUser = null;console.log(maybeUser?.name); // undefined (no crash)console.log(user?.address?.city); // undefined (no crash)// Nullish coalescing (??): fall back ONLY when value is null/undefinedconst input = "";const label1 = input || "Anonymous"; // "Anonymous" (empty string is falsy!)const label2 = input ?? "Anonymous"; // "" (empty string is allowed)
Most real JavaScript work is asynchronous — fetching data, reading a file, waiting for a click. The modern pattern is `async`/`await` (not the older `.then()` chains). You'll learn fetch properly in the APIs lesson; this is the preview.
// async function = always returns a Promiseasync function loadUser(id) {// await pauses inside the async function until the Promise resolvesconst response = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);if (!response.ok) {throw new Error(`HTTP ${response.status}`);}const user = await response.json();return user;}// Use it. Errors bubble out as exceptions you can try/catch.async function main() {try {const user = await loadUser(1);console.log(user.name);} catch (error) {console.error("Failed to load user:", error.message);}}main();// Old style for reference (don't write new code this way)// fetch("...").then(r => r.json()).then(u => console.log(u.name)).catch(...);
In the in-browser editor, open script.js (or add a <script> tag in index.html) and write this. Use modern syntax — `const`, arrow functions, destructuring where it helps.
Declare an array of 5 numbers
Write an arrow function const sumArray = (nums) => ... that returns the total
Write const average = (nums) => sumArray(nums) / nums.length
Log the average to the console using a template literal: `Average: ${average(myNums)}`
Open the browser console (F12) to verify it printed
Bonus: rewrite sumArray as a one-liner using nums.reduce((acc, n) => acc + n, 0)
Hint: it's about whether the variable can change.
Sign in and purchase access to unlock this lesson.