Named Functions
suggest changeFunctions 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.
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:
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'