JavaScript Function Object and Named Function Expressions (NFE)
Learn that JavaScript functions are objects with name and length properties, and how to use Named Function Expressions (NFE) for reliable self-reference.
Functions Are Objects
In JavaScript, every function is an object. That single fact explains a lot of behavior that otherwise looks like magic: you can pass a function around like any value, store it in a variable, read properties off it, and even add your own properties to it.
You already create functions all the time with function declarations and expressions. This chapter looks at what a function is once it exists: an object with useful built-in properties (name and length), the ability to hold custom properties, and a special form — the Named Function Expression — that lets a function reliably refer to itself.
This page assumes you are comfortable with Function Expressions. If let f = function() {...} is new to you, read that first.
The name Property
Every function has a name property holding the function's name as a string. The clever part is that JavaScript fills it in even when there is no name in the obvious place — a behavior called contextual naming.
The engine looks at the assignment and copies the variable name onto the anonymous function. This also works for default parameters and object methods:
There is no magic that always works, though. If there is no name and nothing to copy one from — for example a function created inside an array — name is an empty string:
The name property is handy for logging and debugging: a stack trace that says at sayHi is far more useful than at <anonymous>.
The length Property
A function's length property returns the number of parameters it declares in its definition. Rest parameters (...rest) and parameters with default values are not counted, and counting stops at the first such parameter.
A common real use of length is to introspect a callback. Some libraries call a handler differently depending on how many arguments it expects — for instance, treating a zero-argument handler as "fire once for everyone" and a one-argument handler as "fire once per item".
Custom Properties
Because a function is an object, you can attach your own properties to it. This is different from a local variable: a property lives on the function and survives between calls, so it is a tidy way to give a function its own persistent state.
A classic example is a call counter:
A function property is not the same as a variable inside the function. A local variable resets on every call; a property persists, and it is also readable and writable from the outside, which makes it useful for configuration (such as caching results on the function itself).
Named Function Expressions (NFE)
A Named Function Expression is a function expression that carries a name after the function keyword:
let sayHi = function func(who) {
console.log("Hello, " + who);
};This looks unusual — why give a name to something already assigned to sayHi? The name func here is special in two ways:
- It lets the function reliably refer to itself from inside its own body.
- It is only visible inside the function — you cannot call
func()from outside.
Why the internal name matters
You might think you could just use the outer variable sayHi for self-reference. The problem is that the outer variable can change. With an NFE, the internal name always points to the current function, no matter what happens to the variable:
If the function had called sayHi(\"Guest\") instead of func(\"Guest\"), the call would throw a TypeError because sayHi was set to null. The internal name is immune to that.
NFE and recursion
This self-reference is exactly what recursion needs. An NFE keeps a recursive call working even if the function is later reassigned or passed around under another name — see JavaScript Recursion and Stack for the full picture.
Note that the internal name trick applies only to Function Expressions. A Function Declaration cannot have a separate internal name, and it has no way to hide a name from the outer scope, so it cannot keep a private self-reference in the same way.
When to Use These Features
- Use
namefor clearer logs and debugging output. - Use
lengthwhen writing libraries that adapt to a callback's arity. - Use custom properties to give a function persistent state (counters, caches, configuration) without a surrounding closure or global.
- Use a Named Function Expression whenever a function expression must call itself — especially for recursion or detachable handlers — so the call survives variable reassignment.
Summary
A JavaScript function is an object you can inspect and extend. The name property gives its name (often filled in contextually), length reports its declared parameter count, and you can attach custom properties for persistent state. A Named Function Expression adds an internal-only name that lets a function call itself reliably, which is the safest way to write self-referential and recursive function expressions.