JavaScript Functions Named Functions


Example

Functions can either be named or unnamed (anonymous functions):

var namedSum = function sum (a, b) { // named
    return a + b;
}

var anonSum = function (a, b) { // anonymous
    return a + b;
}

namedSum(1, 3);
anonSum(1, 3);

4
4

But their names are private to their own scope:

var sumTwoNumbers = function sum (a, b) {
    return a + b;
}

sum(1, 3);

Uncaught ReferenceError: sum is not defined

Named functions differ from the anonymous functions in multiple scenarios:

  • When you are debugging, the name of the function will appear in the error/stack trace
  • Named functions are hoisted while anonymous functions are not
  • Named functions and anonymous functions behave differently when handling recursion
  • Depending on ECMAScript version, named and anonymous functions may treat the function name property differently

Named functions are hoisted

When using an anonymous function, the function can only be called after the line of declaration, whereas a named function can be called before declaration. Consider

foo();
var foo = function () { // using an anonymous function
    console.log('bar');
}

Uncaught TypeError: foo is not a function

foo();
function foo () { // using a named function
    console.log('bar');
}

bar


Named Functions in a recursive scenario

A recursive function can be defined as:

var say = function (times) {
    if (times > 0) {
        console.log('Hello!');

        say(times - 1);
    }
}

//you could call 'say' directly, 
//but this way just illustrates the example
var sayHelloTimes = say;

sayHelloTimes(2);

Hello!
Hello!

What if somewhere in your code the original function binding gets redefined?

var say = function (times) {
    if (times > 0) {
        console.log('Hello!');

        say(times - 1);
    }
}

var sayHelloTimes = say;
say = "oops";

sayHelloTimes(2);

Hello!
Uncaught TypeError: say is not a function

This can be solved using a named function

// The outer variable can even have the same name as the function
// as they are contained in different scopes
var say = function say (times) {
    if (times > 0) {
        console.log('Hello!');

        // this time, 'say' doesn't use the outer variable
        // it uses the named function
        say(times - 1);
    }
}

var sayHelloTimes = say;
say = "oops";

sayHelloTimes(2);

Hello!
Hello!

And as bonus, the named function can't be set to undefined, even from inside:

var say = function say (times) {
    // this does nothing
    say = undefined;
    
    if (times > 0) {
        console.log('Hello!');

        // this time, 'say' doesn't use the outer variable
        // it's using the named function
        say(times - 1);
    }
}

var sayHelloTimes = say;
say = "oops";

sayHelloTimes(2);

Hello!
Hello!


The name property of functions

Before ES6, named functions had their name properties set to their function names, and anonymous functions had their name properties set to the empty string.

5
var foo = function () {}
console.log(foo.name); // outputs ''

function foo () {}
console.log(foo.name); // outputs 'foo'

Post ES6, named and unnamed functions both set their name properties:

6
var foo = function () {}
console.log(foo.name); // outputs 'foo'

function foo () {}
console.log(foo.name); // outputs 'foo'

var foo = function bar () {}
console.log(foo.name); // outputs 'bar'