What is JavaScript?
JavaScript is the programming language of the Web. It is what makes websites interactive โ from clicking buttons and submitting forms, to live chat apps and browser-based games. Alongside HTML (structure) and CSS (style), JavaScript is the third pillar of front-end development.
F12, go to the Console tab, and type console.log("Hello, World!") โ you're now running JavaScript!// Your very first JavaScript program console.log("Hello, World!"); console.log("Welcome to JavaScript ๐");
Variables
A variable is a named container that stores a value. Think of it as a labelled box you can put data into and retrieve later. In modern JavaScript, you declare variables using let, const, or the older var.
| Keyword | Reassignable? | Scope | Use When |
|---|---|---|---|
const |
No | Block | Value won't change (preferred) |
let |
Yes | Block | Value may change |
var |
Yes | Function | Legacy code (avoid in new code) |
const name = "Alice"; // string โ won't change let age = 25; // number โ might change let job = "Developer"; // can be reassigned job = "Engineer"; // reassigning let is fine console.log(name); console.log(age); console.log(job);
const by default. Only switch to let when you know the value needs to change. Never use var in new code.Data Types
Every value in JavaScript has a type. There are 7 primitive types plus the special Object type (which includes arrays and functions).
const greeting = "Hello"; // String const score = 42; // Number const isReady = true; // Boolean let nothing; // undefined (no value assigned) const empty = null; // null (intentionally empty) const colors = ["red", "blue"]; // Array (a type of Object) console.log(typeof greeting); // "string" console.log(typeof score); // "number" console.log(typeof isReady); // "boolean" console.log(typeof nothing); // "undefined" console.log(typeof empty); // "object" (historical quirk!) console.log(typeof colors); // "object"
${"{}"}: `Hello, ${"{name}"}!` โ far cleaner than string concatenation.const name = "Alice"; const age = 25; // Old way (messy): // "Hello, " + name + "! You are " + age + " years old." // Modern way (clean): const message = `Hello, ${name}! You are ${age} years old.`; console.log(message);
typeof 42 return in JavaScript?Operators
Operators let you perform calculations, compare values, and combine logic. The most common categories are arithmetic, comparison, and logical.
const a = 10, b = 5; console.log(a + b); // 15 โ addition console.log(a - b); // 5 โ subtraction console.log(a * b); // 50 โ multiplication console.log(a / b); // 2 โ division console.log(a % b); // 0 โ modulo (remainder) โ 10%5=0, 10%3=1 console.log(a ** b); // 100000 โ exponentiation (10^5)
console.log(10 > 5); // true โ greater than console.log(10 < 5); // false โ less than console.log(10 >= 10); // true โ greater than or equal // === checks value AND type (always prefer this) console.log(5 === 5); // true console.log(5 === "5"); // false! number โ string console.log(5 == "5"); // true โ == coerces types (avoid!)
=== (triple equals) for comparisons. The double-equals == performs type coercion which leads to subtle, hard-to-find bugs.Logical Operators, Falsy Values & Nullish
JavaScript has powerful operators for combining conditions and handling missing values. To use them confidently, you first need to understand falsy values โ the handful of values JavaScript treats as false in a boolean context.
// These 6 values are FALSY โ everything else is truthy const falsyValues = [0, "", false, null, undefined, NaN]; falsyValues.forEach(v => { console.log(`${v} is falsy`); }); console.log("---"); // Truthy examples โ watch out for these surprises! const truthyValues = [42, "hello", [], {}]; truthyValues.forEach(v => { console.log(`${JSON.stringify(v)} is TRUTHY`); });
[] and empty object {} are truthy โ only an empty string "" and zero 0 are falsy. This trips up almost every beginner.
&& (AND) and || (OR) don't just return true or false โ they return one of their actual operands. This makes them incredibly useful for short-circuit evaluation and default values.
console.log("--- AND (&&) ---"); // && returns the FIRST falsy value, or the last value if all truthy console.log(false && "hello"); // false โ stops at first falsy console.log("hello" && "world"); // "world" โ both truthy, returns last console.log("--- OR (||) ---"); // || returns the FIRST truthy value, or the last value if all falsy console.log("hello" || "world"); // "hello" โ first truthy wins console.log(0 || "Guest"); // "Guest" โ 0 is falsy, falls through console.log("" || "Guest"); // "Guest" โ "" is falsy, falls through
// || for default values (classic pattern) const greet = (name) => console.log(`Hello, ${name || "Guest"}!`); greet("Alice"); // Hello, Alice! greet(""); // Hello, Guest! โ empty string is falsy // && for conditional execution โ "do this only if that is true" const user = { name: "Alice", isAdmin: true }; user.isAdmin && console.log("User is an admin"); const loggedIn = false; loggedIn && console.log("Dashboard loaded"); console.log("(nothing logged โ user not logged in)");
?? (Nullish Coalescing) solves a key weakness of ||: it only falls back when the left side is null or undefined โ not when it's 0 or "", which are legitimate values.
const scores = { alice: 10, bob: 0 }; // Bob scored zero โ valid! console.log("--- Using || (problem) ---"); console.log(scores.alice || "N/A"); // 10 โ fine console.log(scores.bob || "N/A"); // "N/A" โ BUG! 0 is falsy console.log("--- Using ?? (solution) ---"); console.log(scores.alice ?? "N/A"); // 10 โ fine console.log(scores.bob ?? "N/A"); // 0 โ correct! // ?? only triggers for null / undefined โ not 0 or ""
?. (Optional Chaining) lets you safely access deeply nested properties without crashing when an intermediate value is null or undefined. Instead of an error, it returns undefined.
const users = [ { name: "Alice", address: { city: "Warsaw" } }, { name: "Bob" } // no address! ]; // Without optional chaining โ would CRASH on Bob: // console.log(users[1].address.city) โ TypeError! // With ?. โ safe, returns undefined instead of crashing console.log(users[0]?.address?.city); // "Warsaw" console.log(users[1]?.address?.city); // undefined โ no crash! console.log(users[5]?.address?.city); // undefined โ index out of bounds, no crash! console.log("--- Combined with ?? ---"); // ?. and ?? are best friends โ access safely, then provide fallback console.log(users[0]?.address?.city ?? "Unknown city"); // Warsaw console.log(users[1]?.address?.city ?? "Unknown city"); // Unknown city // Also works for optional method calls const phone = users[1]?.contact?.getPhone?.() ?? "no phone on file"; console.log(phone);
Use
|| when any falsy value should trigger the fallback (e.g. empty string, 0).Use
?? when only null / undefined should trigger it โ 0 and "" are valid.Use
?. whenever a property might not exist to avoid TypeErrors.
0 ?? "default" return??? only falls back on null or undefined. Since 0 is neither, it is returned as-is. Compare with 0 || "default" which would return "default" because 0 is falsy.Conditionals
Conditionals let your program make decisions. The if / else if / else structure executes different blocks of code depending on whether a condition is true or false.
const score = 87; if (score >= 90) { console.log("Excellent! You got an A."); } else if (score >= 75) { console.log("Great score! You passed with distinction."); } else if (score >= 50) { console.log("You passed."); } else { console.log("Try again next time."); }
For simple value-matching, switch is often cleaner than a long chain of else if statements:
const day = "Monday"; switch (day) { case "Monday": console.log("Start your week strong! ๐ช"); break; case "Friday": console.log("Almost the weekend! ๐"); break; default: console.log("Just another day."); }
break keyword do inside a switch statement?break, execution "falls through" into the next case โ a common source of bugs for beginners!Loops
Loops let you repeat a block of code without writing it multiple times. JavaScript offers several looping constructs โ choose the one that fits your situation.
// Classic for loop: init ; condition ; increment for (let i = 1; i <= 5; i++) { console.log(`Lap ${i}`); }
// while loop โ runs as long as condition is true let count = 3; while (count > 0) { console.log(`Countdown: ${count}`); count--; } console.log("Blast off! ๐"); console.log("---"); // for...of โ best way to loop over arrays const fruits = ["Apple", "Banana", "Cherry"]; for (const fruit of fruits) { console.log(fruit); }
Functions
A function is a reusable block of code that performs a specific task. Instead of writing the same code over and over, you define it once in a function and call it whenever needed. Functions are the foundation of organized, maintainable code.
// Define once... function greet(name) { return `Hello, ${name}!`; } // ...call many times console.log(greet("Alice")); console.log(greet("Bob"));
Modern JavaScript also supports arrow functions โ a shorter, cleaner syntax especially popular for small, inline functions:
// Traditional function: // function square(n) { return n * n; } // Arrow function โ same thing, shorter: const square = (n) => n * n; // With multiple lines, use curly braces + return: const circleArea = (radius) => { const pi = 3.14159; return pi * radius ** 2; }; console.log(square(5)); console.log(circleArea(5).toFixed(2));
return keyword do inside a function?return returns undefined by default. Use return when you want the function to produce a value you can use elsewhere.Live Playground
Time to practice! Write your own JavaScript code below and run it. Try combining variables, a function, and a loop to see everything working together.
Lesson Summary
You've covered the core building blocks of JavaScript. Here's what you now know:
const, let variable declarationstypeof${"{}"}0, "", false, null, undefined, NaN&& and || short-circuit evaluation?? nullish coalescing & ?. optional chainingif / else if / else logicswitch statementsfor, while, for...of loops.map(), .filter(), and .reduce() that make working with data elegant and expressive.