What you'll learn
Node.js programs are JavaScript programs. This focused language refresher gives you the values, functions, collections, and data-transformation habits required for every backend lesson that follows.
By the end of this lesson, you'll be able to:
- Choose const and let deliberately and recognize primitive versus reference values
- Write small functions with defaults, rest parameters, and predictable returns
- Transform arrays with map, filter, find, and reduce
- Read and construct objects with destructuring, spread, and optional chaining
Core mental model
Node.js becomes easier when you separate the JavaScript language from the runtime and the operating-system capabilities it exposes. Use this table as a decision guide.
| Concept | What it means | Decision rule |
|---|---|---|
| Value vs reference | Primitives copy values; objects and arrays share references | Copy shared structures before changing them when callers expect immutability |
| Pure function | Output depends on inputs without hidden mutation | Keep business calculations pure; isolate files, logs, and network calls at boundaries |
| Collection pipeline | A sequence of focused transformations | Use map/filter/reduce when each step is clearer than one stateful loop |
| Defensive access | Optional chaining and nullish defaults handle absent data | Validate required input; default only genuinely optional input |
Professional workflow
Build and verify Node.js programs from the terminal in small, observable steps.
- Write down the input and output shape before implementing a transformation.
- Validate required values at the boundary and convert them once.
- Use const by default; introduce let only for intentional reassignment.
- Break multi-step behavior into named functions with one responsibility each.
- Exercise empty, missing, zero, false, and malformed values before refactoring.
Keep the feedback loop short
Guided code lab
Transform server-style records without mutation
The pipeline validates active records, calculates totals, and creates new response objects while leaving the source unchanged.
const orders = [
{ id: 1, active: true, price: 12, quantity: 2 },
{ id: 2, active: false, price: 8, quantity: 4 },
{ id: 3, active: true, price: 5, quantity: 3 },
];
const summaries = orders
.filter((order) => order.active)
.map(({ id, price, quantity }) => ({ id, total: price * quantity }));
console.log(summaries);Normalize optional configuration
Destructuring makes expected fields visible. Nullish coalescing preserves meaningful false and zero values while supplying defaults for null or undefined.
function normalizeConfig(input = {}) {
const {
port = 3000,
logging = true,
database: { host = "localhost" } = {},
} = input;
return { port: Number(port), logging: logging ?? true, host };
}
console.log(normalizeConfig({ port: "8080", logging: false }));Separate validation from calculation
Each function has a clear contract, making failures easier to test and reuse later in an API or CLI.
function assertLine(line) {
if (!Number.isFinite(line.price) || line.price < 0) {
throw new TypeError("price must be a non-negative number");
}
if (!Number.isInteger(line.quantity) || line.quantity < 1) {
throw new TypeError("quantity must be a positive integer");
}
}
function invoiceTotal(lines, taxRate = 0) {
lines.forEach(assertLine);
const subtotal = lines.reduce(
(sum, line) => sum + line.price * line.quantity,
0,
);
return subtotal * (1 + taxRate);
}
console.log(invoiceTotal([{ price: 20, quantity: 2 }], 0.1));Production practice
Validate once
Convert untrusted strings and validate required fields at the program boundary; keep the inner model consistent.
Avoid hidden mutation
Return new objects from transformations unless the function clearly documents in-place behavior.
Prefer clarity
A direct loop is better than a clever pipeline when it makes state, errors, or early exits easier to follow.
Common failure mode
Independent workshop
Build an inventory report that validates raw product records, keeps only available items, computes stock value, and returns a summary object.
Your finished workshop must include:
- Separate normalize, validate, and summarize functions
- No mutation of the input array or its objects
- Useful errors for invalid price and quantity
- Examples covering empty inventory and zero stock
Definition of done
Recap & quick check
Key takeaways
- Node.js uses ordinary modern JavaScript
- Pure functions keep core logic testable
- Array methods express focused transformations
- Destructuring documents consumed shapes
- Nullish defaults preserve false and zero
Quick check
1. Which declaration should be the default for a binding that will not be reassigned?
2. Which method creates one output element for every input element?
3. Why use ?? instead of || for a numeric configuration value?
4. What does object spread create?
Next: Inside the Node.js Runtime