Defining Functions in JavaScript

Introduction

JavaScript offers several ways to define functions—declarations, expressions, arrows, and methods on objects. Each style has different hoisting, this behavior, and readability. This chapter compares them so you can choose consistently in real projects.

Prerequisites

Function Declaration

javascript
// Available in entire scope (hoisted)
function multiply(a, b) {
  return a * b;
}
 
console.log(multiply(3, 4));

You can call multiply before its line in the file because declarations are hoisted.

Function Expression

javascript
// Not hoisted like declarations
const divide = function (a, b) {
  return a / b;
};
 
console.log(divide(10, 2));

Named function expression (useful for stack traces):

javascript
// Name visible inside only
const factorial = function fact(n) {
  if (n <= 1) return 1;
  return n * fact(n - 1);
};
 
console.log(factorial(5));

Arrow Function Expression

javascript
// Concise, no own `this`
const square = (n) => n * n;
const sum = (a, b) => a + b;
 
console.log(square(5));
console.log(sum(1, 2));

Multi-line body needs braces and return:

javascript
// Block body with return
const describe = (name) => {
  const label = name.toUpperCase();
  return `User: ${label}`;
};
 
console.log(describe("ada"));

Methods on Objects

javascript
// Method shorthand in object literal
const calculator = {
  value: 0,
  add(n) {
    this.value += n;
    return this;
  },
  reset() {
    this.value = 0;
  },
};
 
calculator.add(5).add(3);
console.log(calculator.value);
calculator.reset();

Generator / Async (Mention Only)

async function and function* appear in later chapters on Promises and iterators—same function keyword family.

When to Use Which Style

StyleGood for
DeclarationTop-level utilities, hoisting needed
ExpressionAssign to const, conditional creation
ArrowCallbacks, short transforms, lexical this
MethodObject behavior with this

Mini Example: Plugin Registry

javascript
// Store named handlers
const plugins = {};
 
function register(name, handler) {
  plugins[name] = handler;
}
 
register("echo", (msg) => console.log(msg));
register("shout", (msg) => console.log(msg.toUpperCase()));
 
plugins.echo("hello");
plugins.shout("hello");

FAQ

Can I reassign a const function?

const fn = ... prevents reassigning fn, but you can replace properties on objects holding functions.

Arrow as object method?

Avoid const obj = { run: () => this } when you need this to be obj—use run() { } shorthand.

Is new function(){} valid?

Rare pattern for dynamic code—prefer normal declarations in learning projects.

What comes next?

Parameters and return.