Skip to content

Latest commit

 

History

History
140 lines (104 loc) · 2.76 KB

File metadata and controls

140 lines (104 loc) · 2.76 KB

Named Function Expression

Named Function Expression or, shortly, NFE, is a term a Function Expression that has a name.

For instance, let's take an ordinary Function Expression:

let sayHi = function(who) {
  alert(`Hello, ${who}`);
};

...And add a name to it:

let sayHi = function *!*func*/!*(who) {
  alert(`Hello, ${who}`);
};

What's the role of that additional "func" name?

First let's note, that we're still having a Function Expression. Adding the name "func" after function did not make it a Function Declaration, because it is still created as a part of an assignment expression.

Adding such a name also did not break anything.

The function is still available as sayHi():

//+ run
let sayHi = function *!*func*/!*(who) {
  alert(`Hello, ${who}`);
};

sayHi("John"); // Hello, John

There are two special things about the name func:

  1. It allows to reference the function from inside itself.
  2. It is not visible outside of the function.

For instance, the function sayHi below re-calls itself with "Guest" if no who is provided:

//+ run
let sayHi = function *!*func*/!*(who) {
  if (who) {
    alert(`Hello, ${who}`);
  } else {
*!*
    func("Guest"); // use func to re-call itself
*/!* 
  }
};

sayHi(); // Hello, Guest

// But this won't work: 
func(); // Error, func is not defined (not visible outside of the function)

Later we'll see more cases when a function wants to re-call itself with modified parameters.

So, why won't we use sayHi for the nested call?

Actually, in most cases we can:

let sayHi = function(who) {
  if (who) {
    alert(`Hello, ${who}`);
  } else {
*!*
    sayHi("Guest");
*/!* 
  }
};

The problem with the latter code is that the value of sayHi may change. The function may go to another variable:

//+ run
let sayHi = function *!*func*/!*(who) {
  if (who) {
    alert(`Hello, ${who}`);
  } else {
*!*
    func("Guest"); // (*)
*/!* 
  }
};

let welcome = sayHi;
sayHi = null;

welcome(); // Hello, Guest (still works under different name)

Using func in the line (*) guarantees that this exactly function will be called. Using sayHi there

...But the name func is not visible outside of the function:

//+ run
let sayHi = function *!*func*/!*(who) {
  // ...
};

*!*
func(); // Error: func is not defined
*/!*

Named Function Expressions are used in rare cases when:

  • The function needs to reference itself from inside. For instance, call itself with another arguments.
  • The function travels between variables.

The code below demonstrates both conditions:

//+ run
let sayHi = function *!*func*/!*(name) {
  if (name) {
    alert(`Hello, ${name}!`)
  } else {
    func("Guest");
  }
};

welcome(); // Works