ModernCS
Session 1.190 minFree preview

JavaScript, Server Side

Values, functions, arrays, objects, and running a file with node.

By the end of this session you will be able to:

  • Run a JavaScript file on your own machine with node report.js and read exactly what it prints
  • Choose between const and let on purpose, and predict what typeof returns for any value you write
  • Reshape a list of records with filter, map, and reduce, and pull fields out of objects with destructuring

No browser, no page, no button

Most JavaScript you have seen runs inside a web page. It reacts to a click, changes some text, and disappears when the tab closes. Node runs the same language on the same engine, V8, but hands it a different set of doors: files, sockets, processes, the clock. There is no document, no window, no alert. Paste alert("hi") into a Node file and you get ReferenceError: alert is not defined. That is correct behavior, not a broken install.

First, find out what you have:

node --version

This course targets Node.js 26, which became the Current release in May 2026. Node 24, codename Krypton, is the Active LTS and will run everything in this phase identically. If you see anything below v24, upgrade before you go further, because half of what phase one covers did not exist yet.

Now make a file. Anywhere you like, as long as you can find it again:

mkdir catalog
cd catalog

Put this in hello.js:

console.log("running on Node", process.version);
console.log(2 + 2);

Run it:

node hello.js
running on Node v26.6.0
4

That is the whole loop: a file, a command, output in your terminal. process is one of the globals Node gives you that a browser does not.

Two more things the runtime hands you for free. Typing bare node with no file starts the REPL, an interactive prompt where each line runs as you type it, which is the fastest way to check what an expression evaluates to. Press Ctrl-D or type .exit to leave. For a one-off answer, node -p "2 ** 10" evaluates the string and prints the result.

Values, and the two ways to name them

You name a value with const or with let. Use const by default, and let only when the name genuinely needs to point at a different value later. There is a third keyword, var, which you will see in old code and should not write.

JavaScript's primitive types are string, number, boolean, null, and undefined, plus bigint and symbol you will rarely touch. Everything else, including arrays and functions, is an object.

const port = 3000;
const service = "catalog";
let requests = 0;
 
requests = requests + 1;
 
console.log(`${service} listening on ${port}, ${requests} request so far`);
console.log(typeof port, typeof service, typeof null, typeof undefined);
catalog listening on 3000, 1 request so far
number string object undefined

Backticks give you a template literal, where ${} drops any expression into the string. Note the third value on that last line: typeof null is "object", which is a bug shipped in 1995 and never fixed because too much code depends on it. Memorize it and move on.

Compare with ===, never with ==. The double equals converts types before comparing, so "10" == 10 is true and so is [] == false. The triple equals compares type and value, and gives you the answer you meant.

Functions are the unit you reuse

A function takes arguments, does work, and returns a value. If it never hits a return, it returns undefined.

function formatBook(book) {
  return `${book.title} by ${book.author} (${book.year})`;
}
 
const shout = (text) => text.toUpperCase();
 
function overdueFee(daysLate, perDay = 0.25) {
  if (daysLate <= 0) return 0;
  return daysLate * perDay;
}
 
console.log(formatBook({ title: "Dune", author: "Herbert", year: 1965 }));
console.log(shout("late"));
console.log(overdueFee(4), overdueFee(4, 1));
Dune by Herbert (1965)
LATE
1 4

Three forms worth knowing. function name() {} is a declaration. (text) => text.toUpperCase() is an arrow function with an implicit return: no braces, so the expression is the return value. Add braces and you need an explicit return again. And perDay = 0.25 is a default parameter, used only when the caller passes nothing.

Arrays and objects are the shape of all your data

An array is an ordered list. An object is a set of named fields. Nest them and you have the shape of every API response and every database row you will handle for the rest of this course.

const books = [
  { title: "Dune", author: "Herbert", year: 1965, copies: 3 },
  { title: "Solaris", author: "Lem", year: 1961, copies: 0 },
  { title: "Roadside Picnic", author: "Strugatsky", year: 1972, copies: 5 },
];
 
const available = books.filter((book) => book.copies > 0);
const titles = available.map((book) => book.title);
const totalCopies = books.reduce((sum, book) => sum + book.copies, 0);
 
console.log(titles);
console.log(totalCopies);
 
const [firstBook] = books;
const { title, year } = firstBook;
console.log(title, year);
[ 'Dune', 'Roadside Picnic' ]
8
Dune 1965

filter keeps the elements where your function returns true. map transforms each element into something else. reduce folds the whole list into a single value, starting from the 0 you passed as its second argument. All three return something new and leave books untouched.

The last two lines are destructuring. const [firstBook] = books pulls out element zero by position, and const { title, year } = firstBook pulls out fields by name.

One thing will confuse you the first time it happens. console.log formats objects only two levels deep, then gives up:

const config = { db: { pool: { max: { size: 10 } } } };
console.log(config);
{ db: { pool: { max: [Object] } } }

Your data is fine. The printer stopped. When you need to see all of it, use console.dir(config, { depth: null }).

Try it

In your catalog folder, write report.js.

  1. Define a books array with at least five entries, each an object with title, author, year, and copies. At least two of them must have copies set to 0.
  2. Write a function summarize(books) that returns a single object with three fields: total (how many books are in the array), available (how many have at least one copy), and oldest (the title of the book with the smallest year).
  3. Call it and print the result with console.log.

Run it:

node report.js

You are done when node report.js prints one object with those three fields, and when changing any book's copies to 0 lowers available by one without you editing summarize at all.

Common mistakes

  • Thinking const freezes the value. It does not. const list = [] followed by list.push("Dune") works fine. const only stops the name from being reassigned to a different value. This is what people mean when they say const is about the binding, not the contents.
  • Calling filter or map and throwing away the result. A line that reads books.filter((book) => book.copies > 0); on its own does nothing at all. These methods return a new array, so assign it. The methods that do change the original are push and sort, and sort reorders in place, which will bite you when something else was still holding that array.
  • Writing (x) => { x * 2 } and getting undefined. Adding braces turns the arrow body into a block, and a block needs an explicit return. Either drop the braces or write return x * 2;.
  • node report.js says Cannot find module. The path is resolved from the directory you are standing in, not from where the file lives. Run ls first and confirm the file is actually there. Node is not lying to you about this one.
  • Comparing with == because it looks cleaner. It is not cleaner, it is a coercion table you do not want to memorize. Use the triple equals everywhere.

Where this goes next

Right now everything lives in one file, which stops working the moment you have more than about a hundred lines. Next session, Modules, npm, and node_modules, splits that file into several with export and import, introduces package.json, and opens up node_modules to show you exactly what npm install put on your disk.

That was one session of 5 in this phase.

Backend Web runs to 4 phases. Buy the whole course, or just the phase you need.