Function Expressions
A function expression is a function used as a value — typically assigned to a variable, passed to another function, or returned from one. It looks almost identical to a function declaration, but the difference in when the function exists and how it is referred to changes how you can use it.
Anonymous function expressions
The most common shape: the function keyword has no name and the whole expression is assigned to a variable.
const greet = function (name) {
return "Hello, " + name;
};
console.log(greet("Ada"));Hello, Ada
The function itself has no name; the variable greet happens to hold it. In modern engines, the variable name is inferred as the function's name property — handy in stack traces.
console.log(greet.name); // "greet" (inferred from the variable)
Named function expressions
You can also give the function its own name, even when assigning it to a variable. The name is only visible inside the function — useful for recursion or self-referencing without depending on the outer variable.
const factorial = function fact(n) {
if (n <= 1) return 1;
return n * fact(n - 1); // uses the internal name
};
console.log(factorial(5)); // 120
// console.log(fact(5)); // ReferenceError — "fact" not visible out hereExpressions vs declarations
The two forms compile to functions, but behave differently around hoisting and naming:
Function declaration —
function foo() {}at statement position. Hoisted entirely: callable above the line where it appears.Function expression — used as a value, often
const foo = function () {}. The variable declaration is hoisted (forvar) or in the temporal dead zone (forlet/const), but the function value is not assigned until that line runs.
hello(); // works — declaration is hoisted
function hello() { console.log("hi"); }
// goodbye(); // TypeError — assigned later
const goodbye = function () { console.log("bye"); };
goodbye(); // now it worksWhen to reach for each
Use a declaration when defining a top-level helper that the rest of the file calls. Hoisting and a clean name make the file readable.
Use an expression when the function is a value — assigned to a variable, used as a callback, passed to another function, or stored in an object.
Use a named expression when you need to self-reference inside the body, want a stable name in stack traces, or are building something recursive without polluting an outer name.
For most "function-as-a-value" cases today, an arrow function is shorter and idiomatic — see Arrow Functions.
As callbacks and arguments
Function expressions shine when a function only needs to exist long enough to be passed somewhere.
const numbers = [1, 2, 3, 4];
const doubled = numbers.map(function (n) {
return n * 2;
});
console.log(doubled); // [2, 4, 6, 8]
setTimeout(function () {
console.log("tick");
}, 1000);Arrow functions are usually preferred for these cases now, but the function-expression form is still legal and shows up in older codebases.
The function name property
Every function has a name property. JavaScript tries to give it a useful value automatically:
function declared() {}
const inferred = function () {};
const explicit = function explicitName() {};
const arrow = () => {};
const obj = { method() {} };
console.log(declared.name); // "declared"
console.log(inferred.name); // "inferred" (inferred from variable)
console.log(explicit.name); // "explicitName"
console.log(arrow.name); // "arrow"
console.log(obj.method.name); // "method"