Functions are reusable blocks of code. In JavaScript, functions are first-class values: they can be assigned, passed as arguments, and returned from other functions.
function add(a, b) { return a + b;}const add = function (a, b) { return a + b;};const add = (a, b) => a + b;Arrow functions are shorter, but they also behave differently with this.
function greet(name = "Guest") { return `Hello, ${name}`;}function sum(...numbers) { return numbers.reduce((total, n) => total + n, 0);}const values = [1, 2, 3];console.log(sum(...values));A function can return any value, including objects and other functions.
function createUser(name) { return { name };}this and Arrow FunctionsRegular functions get their own this depending on how they are called.
Arrow functions do not create their own this; they capture it lexically from the outer scope.
const user = { name: "Tom", normal() { console.log(this.name); }, arrow: () => { console.log(this.name); },};In object methods, regular functions are usually the safer choice.
A function can access variables from its outer scope. That behavior is called a closure.
function createCounter() { let count = 0;
return function () { count += 1; return count; };}
const counter = createCounter();console.log(counter()); // 1console.log(counter()); // 2Closures are extremely useful for encapsulation and state preservation.
async/awaitFunctions are the foundation of asynchronous JavaScript:
function fetchData(callback) { setTimeout(() => callback("done"), 1000);}Modern code more often uses:
async function loadData() { const result = await Promise.resolve("done"); return result;}A higher-order function takes a function as an argument or returns one.
const numbers = [1, 2, 3];const doubled = numbers.map((n) => n * 2);This style is common in modern JavaScript.
const multiply = (a) => (b) => a * b;const double = multiply(2);const double = (x) => x * 2;const increment = (x) => x + 1;
const composed = (x) => increment(double(x));JavaScript does not support TypeScript-style overload signatures in plain runtime code. The usual approach is to inspect arguments manually:
function format(value, options) { if (typeof value === "number") { return value.toFixed(options?.digits ?? 2); }
return String(value);}const for function references by defaultarguments vs rest parametersPrefer rest parameters in modern code:
function sum(...values) { return values.reduce((a, b) => a + b, 0);}thisconst user = { name: "Tom", say() { console.log(this.name); },};
const fn = user.say;fn(); // `this` is not `user`You may need bind, a wrapper function, or a different call site.
Functions are one of the most important parts of JavaScript. To use them well, you need more than syntax:
this