Functions
Scope: declarations, arrow functions, parameters, and callbacks. All examples were run with Node v24.
Declarations
function add(a, b) {
return a + b;
}
console.log(add(2, 3)); // 5
No types on parameters or returns — JavaScript figures it out at runtime (and sometimes gets it wrong; that's the tradeoff).
Default parameters
function greet(name = "stranger") {
return `Hello, ${name}!`;
}
greet(); // Hello, stranger!
greet("Ada"); // Hello, Ada!
Rest parameters: any number of arguments
function sum(...nums) {
return nums.reduce((total, n) => total + n, 0);
}
sum(1, 2, 3); // 6
...nums collects extra arguments into an array.
Arrow functions
const double = (x) => x * 2;
const add = (a, b) => a + b;
const greet = (name) => {
const msg = `Hello, ${name}!`;
return msg;
};
- One expression: the braces and
returnvanish, the value is returned automatically. - Multiple statements: keep the braces and
return.
Arrows are the modern default for short functions and callbacks.
Use function for top-level named functions — it reads better.
The this gotcha (arrows vs function)
Regular functions get their own this (which changes depending
on how they're called — a notorious source of bugs). Arrow
functions inherit this from where they're written. Rule of
thumb: use arrows for callbacks, and you'll dodge 90% of
this confusion. Full this semantics are beyond these guides'
scope — reach for them only when a bug forces you to.
Callbacks: functions as arguments
const nums = [1, 2, 3, 4];
const doubled = nums.map((n) => n * 2); // [2, 4, 6, 8]
const evens = nums.filter((n) => n % 2 === 0); // [2, 4]
Passing small functions into map/filter/forEach is the
bread and butter of JavaScript. The array methods to know:
| Method | Does what |
|---|---|
map |
Transforms each element, returns a new array |
filter |
Keeps elements that pass the test |
find |
First element that passes the test |
forEach |
Runs the function on each (returns nothing) |
reduce |
Boils the array down to one value |
These return new arrays — they don't modify the original
(forEach aside, which is for side effects).
Closures
function makeCounter() {
let count = 0;
return () => ++count;
}
const counter = makeCounter();
counter(); // 1
counter(); // 2
The returned arrow "remembers" count from where it was created.
That's a closure — functions carrying their birth
environment with them. You'll use this pattern for handlers,
timers, and private state.
Check
- [ ] You can write declaration, arrow, and callback forms
- [ ] You know when braces/
returncan be dropped from an arrow - [ ] You can
map/filteran array from memory
Next: Async JavaScript.