JavaScript Quick Reference
This is a programmer-oriented reference for JavaScript constructs used in the course. It progresses from variables and functions through collections, modules, and asynchronous work, with examples adapted to the current materials.
You can read the examples as reference or try the small language examples in a browser console. Each block is a separate example. Use a fresh console context or a separate script when reusing names declared with const or let.
Examples using separate module files need a module-capable environment, such as the project introduced in the course; they are not all single console statements.
For a first pass, focus on values and bindings, functions, conditionals, objects, arrays, collection transformations, modules, and promises. The mutating-array and additional-collection sections are primarily for looking up unfamiliar operations.
Values, bindings, and scope
JavaScript values include numbers, strings, booleans, objects, null, and undefined. A binding associates a name with a value:
const courseTitle = "Web software";let completed = 0;completed = completed + 1;console.log(`${courseTitle}: ${completed}`);// Web software: 1Use const when the binding will not be reassigned and let when reassignment is needed. Both are block-scoped: a binding declared inside an if block belongs to that block and its nested scopes.
const does not make an object immutable:
const room = { name: "Cedar", capacity: 6 };room.capacity = 8; // allowed: the object changes// room = { name: "Birch", capacity: 4 }; // not allowed: reassignmentThis distinction matters when reading state updates. “The variable is constant” does not mean the object cannot change.
Strings can use single quotes, double quotes, or template literals with backticks. Template literals evaluate expressions inside ${...}. The course primarily uses double quotes for strings and backticks for template literals.
Comparisons and missing values
Use strict equality when comparing values without implicit type conversion:
console.log(5 === 5); // trueconsole.log(5 === "5"); // falseconsole.log(5 !== "5"); // trueObject equality compares identity, not all properties:
const first = { name: "Cedar" };const second = { name: "Cedar" };console.log(first === second); // falseconsole.log(first.name === second.name); // trueundefined often means a property, argument, or result is missing. null is commonly used when code deliberately represents no value:
const room = { name: "Cedar", equipment: null };console.log(room.floor); // undefinedconsole.log(room.equipment); // nullA condition converts its value to a boolean. Values such as false, 0, "", null, undefined, and NaN are falsy; an empty array or object is truthy. Prefer explicit conditions when these differences affect a requirement.
const rooms = [];if (rooms.length === 0) { console.log("No rooms found");}Nullish coalescing supplies a default only for null or undefined:
const count = 0;console.log(count ?? 10); // 0console.log(count || 10); // 10Optional chaining safely accesses a property when an intermediate value may be missing:
const selectedRoom = null;console.log(selectedRoom?.name ?? "Choose a room");// Choose a roomFunctions
The course normally assigns an arrow function to a const binding. const prevents the binding from being reassigned, while the arrow function defines the reusable behavior:
const capacityLabel = (capacity) => { return `${capacity} seats`;};
const roomLabel = (name, capacity) => { return `${name}: ${capacityLabel(capacity)}`;};
console.log(roomLabel("Cedar", 6)); // Cedar: 6 seatsAn arrow function with an expression body returns that expression:
const double = (number) => number * 2;console.log(double(3)); // 6An arrow function with a block body needs an explicit return to return a value. Reaching the end without returning produces undefined.
Default parameters apply when an argument is omitted or is undefined:
const greeting = (name = "visitor") => `Hello, ${name}!`;console.log(greeting()); // Hello, visitor!console.log(greeting("Noor")); // Hello, Noor!Passing null does not activate that default. A function call and a function value are also different:
const report = () => "Ready";const action = report; // stores the functionconst result = report(); // calls the functionEvent handlers and test functions often receive a function to call later.
Conditionals and loops
Use if, else if, and else to choose a branch:
const capacity = 6;let label;if (capacity >= 10) { label = "Large";} else if (capacity >= 4) { label = "Medium";} else { label = "Small";}console.log(label); // MediumA conditional expression selects a value:
const available = true;const label = available ? "Available" : "Unavailable";Use for...of to visit values in an array:
for (const name of ["Cedar", "Birch"]) { console.log(name);}A loop is often clearer than a complicated chain of expressions. Choose the form that makes the transformation or side effect easiest to follow.
Object patterns, destructuring, and spread
Objects associate property names with values:
const room = { id: 7, name: "Cedar", capacity: 6 };console.log(room.name); // Cedarconsole.log(room["capacity"]); // 6Destructuring extracts properties into bindings:
const room = { name: "Cedar", capacity: 6 };const { name, capacity } = room;console.log(name, capacity); // Cedar 6It can also rename a binding or give it a default:
const room = { name: "Cedar" };const { name: roomName, capacity = 1 } = room;Spread can make a shallow copy with a changed property:
const room = { name: "Cedar", capacity: 6 };const largerRoom = { ...room, capacity: 8 };console.log(room.capacity); // 6console.log(largerRoom.capacity); // 8Later properties override earlier ones. A shallow copy still shares nested objects:
const first = { equipment: { display: true } };const second = { ...first };second.equipment.display = false;console.log(first.equipment.display); // falseArrays
Arrays store ordered values and use zero-based indexes:
const names = ["Cedar", "Birch"];console.log(names[0]); // Cedarconsole.log(names.length); // 2Transforming collections
Use map when each input should produce an output, filter when deciding which values remain, and find when looking for one matching value:
const rooms = [ { id: 1, name: "Cedar", capacity: 6 }, { id: 2, name: "Birch", capacity: 2 }, { id: 3, name: "Maple", capacity: 8 }];
const names = rooms.map((room) => room.name);const groupRooms = rooms.filter((room) => room.capacity >= 6);const selected = rooms.find((room) => room.id === 2);
console.log(names); // ["Cedar", "Birch", "Maple"]console.log(groupRooms.length); // 2
if (selected === undefined) { console.log("No matching room");} else { console.log(selected.name); // Birch}find returns undefined when nothing matches. map and filter return new arrays, but they do not automatically clone each contained object.
some asks whether any value matches, and every asks whether all values match. reduce accumulates a result:
const capacities = [6, 2, 8];const total = capacities.reduce((sum, capacity) => sum + capacity, 0);console.log(total); // 16Supply the initial value deliberately, including for empty collections. A simple loop may be more readable for a more involved calculation.
Mutating and copying arrays
Some operations mutate an array:
const names = ["Cedar", "Birch"];console.log(names.push("Maple")); // 3: the new lengthconsole.log(names.pop()); // Maple: the removed last valueconsole.log(names.shift()); // Cedar: the removed first valueconsole.log(names); // ["Birch"]splice(start, deleteCount, ...items) removes and optionally inserts values. Its second argument is a count, not an ending index. It returns an array of the removed values:
const names = ["Cedar", "Birch", "Maple", "Pine"];const removed = names.splice(1, 2);console.log(removed); // ["Birch", "Maple"]console.log(names); // ["Cedar", "Pine"]By contrast, slice(start, end) produces a shallow copy of a range, excluding the ending index, without removing values from the original array.
Array spread creates a new array, but the same shallow-copy caveat applies to its object elements:
const names = ["Cedar", "Birch"];const extended = [...names, "Maple"];The ECMAScript array specification is the normative reference for these operations. In everyday reading, pay attention to both the returned value and whether the original collection changes.
JSON is text
A JavaScript object and a JSON document are not the same thing:
const room = { name: "Cedar", capacity: 6 };const text = JSON.stringify(room);const parsed = JSON.parse(text);
console.log(typeof text); // stringconsole.log(parsed.capacity); // 6JSON has a restricted set of values. It does not directly represent functions, undefined, or all JavaScript object types. Parsing valid JSON also does not prove that the resulting object has the fields your application expects. Part 3 introduces validation at that boundary.
Modules: more than one file
A module can export values and import values from other modules. Named exports keep the names explicit:
export const capacityLabel = (capacity) => `${capacity} seats`;export const canFit = (room, people) => room.capacity >= people;import { capacityLabel, canFit } from "./room-utils.js";console.log(capacityLabel(6));console.log(canFit({ capacity: 6 }, 4));A module can also have one default export:
const greeting = (name) => `Hello, ${name}!`;
export default greeting;import greeting from "./greeting.js";console.log(greeting("Noor"));Relative paths are resolved from the importing file. Bare imports such as "hono" rely on the project’s package/import configuration. The supplied starter handles that configuration; this reference does not ask you to install dependencies.
In a plain browser page, a module entry is loaded with type="module":
<script type="module" src="./app.js"></script>Do not add standalone script tags to a page to work around an import that does not work and that you have not understood.
Exceptions and cleanup
A function can throw an error when it cannot fulfill its contract:
const readCapacity = (value) => { const number = Number(value); if (!Number.isInteger(number) || number < 1) { throw new Error("Capacity must be a positive integer"); } return number;};
try { console.log(readCapacity("6")); // 6} catch (error) { console.error(error.message);}catch handles an exception and finally runs cleanup whether the operation succeeds or fails.
Promises and asynchronous functions
A promise represents an operation that may finish later, either with a value or with a failure. Adding async to an arrow function makes its result a promise:
const getRoomName = async () => "Cedar";
const showRoom = async () => { const name = await getRoomName(); console.log(name); // Cedar};
showRoom();await suspends that asynchronous function until the promise settles. It does not freeze the entire browser while unrelated work waits. Here is a small ordering example:
const show = async () => { console.log("A"); await Promise.resolve(); console.log("B");};
show();console.log("C");// A// C// BA rejected promise becomes an exception at the await point:
const demonstrateFailure = async () => { try { await Promise.reject(new Error("Room service unavailable")); } catch (error) { console.log(error.message); }};
demonstrateFailure();The ECMAScript promise specification defines promises. The course uses async and await for readable asynchronous control.
Starting work together or in sequence
Use sequential await when the next operation needs the previous result. Independent operations can be started together and awaited with Promise.all:
const getRooms = async () => ["Cedar", "Birch"];const getOpeningHours = async () => "08:00-18:00";
const loadPageData = async () => { const [rooms, hours] = await Promise.all([ getRooms(), getOpeningHours() ]); return { rooms, hours };};Promise.all rejects if an input promise rejects. It does not automatically cancel the remaining work. Also, array.forEach(async (...) => ...) does not wait for all of its asynchronous callbacks. Use an explicit loop for sequential work or a suitable promise aggregation for concurrent work.
Additional collections: maps and sets
Arrays and objects are sufficient for most course examples. Use Map or Set when its particular key or uniqueness behavior improves the model.
A Map maintains key-value entries:
const roomsById = new Map();roomsById.set(7, { name: "Cedar" });console.log(roomsById.has(7)); // true
const storedRoom = roomsById.get(7);if (storedRoom !== undefined) { console.log(storedRoom.name); // Cedar}
roomsById.delete(7);A Set stores unique values:
const tags = new Set(["quiet", "accessible", "quiet"]);console.log(tags.size); // 2console.log(tags.has("quiet")); // trueDo not add an extra collection type when it does not improve the model.
JavaScript and host APIs
JavaScript is the language. A browser supplies APIs such as document; Deno supplies APIs such as Deno.serve. Not every global name exists in both environments. The same language can run on either side of an HTTP connection while having different capabilities and responsibilities.
There is library and framework-specific syntax that is not part of the JavaScript language. For example, Svelte has specific syntax such as $state. Such syntax is introduced when it is first used.
Where this reference leads
Part 1 uses JavaScript and TypeScript in an already configured application. Part 2 applies functions, objects, arrays, modules, and promises in browser components and HTTP requests. Part 3 uses the same language in server and database code, with runtime validation at external boundaries. Use the TypeScript Quick Reference when static types become the unfamiliar part of an example.