JavaScript Function object, NFE

In the previous chapters, we have already learned that functions in JavaScript are values. Also, each JavaScript value has a type.

Now, it’s time to learn the types of functions.

Functions are objects in JavaScript. It is possible not only to call objects, but to deal with them as objects (add or remove properties, pass by reference, and more).

The Property “name”

The function objects consist of usable properties. It’s demonstrated in the example below:

function welcomeSite() {
  console.log("Welcome to W3Docs");
}
console.log(welcomeSite.name); // welcomeSite

The name-assigning logic gives the right name to a function, even if it’s made without it: Let’s look at the following example:

let welcomeSite = function () {
  console.log("Welcome to W3Docs");
};
console.log(welcomeSite.name); // welcomeSite

It is actual even when a default value implements an assignment:

function f(welcomeSite = function () {}) {
  console.log(welcomeSite.name); // welcomeSite, it works
}
f();

This feature is known as “contextual name.”

The object methods also have names.

For instance:

let site = {
  welcomeSite() {
    // ...
  },
  welcomeSiteBook: function () {
    // ...
  }
}
console.log(site.welcomeSite.name); // welcomeSite
console.log(site.welcomeSiteBook.name); // welcomeSiteBook

When there is no way to find out the correct name, the name property turns out empty, like this:

// function created inside array
let arr = [function () {}]; 
console.log(arr[0].name); // <empty string>
//the engine doesn't have a way of setting up the correct name.

However, as a rule most of the functions have names.

The “length” Property

Another significant property is the “length” property. It is used for returning the number of function parameters.

For example:

function func1(arg1) {}
function func2(arg1, arg2) {}
function func(arg1, arg2, ...args) {}

console.log(func1.length); // 1
console.log(func2.length); // 2
console.log(func.length); // 2

In the example above, the rest of the parameters are not included.

At times, you can use the length property to introspect in the functions operating on other functions.

Custom Properties

You can choose to add your own properties, as well.

You can use the counter property for tracking the total calls count.

It is visualized in the following example:

function welcomeSite() {
  console.log("Welcome to W3Docs");
  welcomeSite.counter++;   // let's count how many times we run
}
welcomeSite.counter = 0; // initial value
welcomeSite(); // Welcome to W3Docs
welcomeSite(); // Welcome to W3Docs
welcomeSite(); // Welcome to W3Docs 
console.log(`Called ${welcomeSite.counter} times`); // Called 3 times

Take into account that a property is not a variable. Hence, a property counter and a let counterlet counter variable can not be related to each other.

A function can be treated as an object, store properties, but it won’t affect its execution.

Named Function Expression

The Named Function Expression (NFE) is for the Function Expressions having a name.

An ordinary Function Expression looks like this:

let welcomeSite = function (user) {
  console.log(`Welcome to W3Docs, dear ${user}`);
};

You can add a name to it:

let welcomeSite = function func(user) {
  console.log(`Welcome to W3Docs, dear ${user}`);
};

Note that adding a name "func" after the function can’t transform it into a Function Declaration, as it is a part of an assignment expression.

The function remains as follows:

let welcomeSite = function func(user) {
  console.log(`Welcome to W3Docs, dear ${user}`);
};
welcomeSite("David"); // Welcome to W3Docs, dear David

The name "func" allows the function referencing itself internally. Moreover, there is no possibility of seeing it outside of the function.

Let’s see the example below:

let welcomeSite = function func(user) {
  if (user) {
    console.log(`Welcome to W3Docs, dear ${user}`);
  } else {
    func("Guest"); // use func to re-call itself
  }
};
welcomeSite(); // Welcome to W3Docs, dear Guest
// But this won't work:
func(); // Error, func not visible outside of the function

In this case, the welcomeSite function calls itself with "Guest", if the user is not provided.

In a variety of cases, you can act like this:

let welcomeSite = function (user) {
  if (user) {
    console.log(`Welcome to W3Docs, dear ${user}`);
  } else {
    welcomeSite("Guest");
  }
};
let sayWelcome = welcomeSite;
sayWelcome();

But there can be a problem with such codes: welcomeSite might transform into external code. In case, the function is assigned to another variable instead, errors will occur in the code:

let welcomeSite = function (user) {
  if (user) {
    console.log(`Welcome to  W3Docs, dear ${user}`);
  } else {
    welcomeSite("Guest"); // Error: welcomeSite is not a function
  }
};
let sayWelcome = welcomeSite;
welcomeSite = null;
sayWelcome(); // Error, the nested welcomeSite call doesn't work any more

Such a scenario happens because the function takes welcomeSite from the external Lexical Environment. No local welcomeSite exists. Hence, the external variable is used. So, during the call, the external welcomeSite may become null .

The optional name you may put into the Function Expression is capable of solving issues like that.

You can use it for fixing your code, like here:

let welcomeSite = function func(user) {
  if (user) {
    console.log(`Welcome to W3Docs, dear ${user}`);
  } else {
    func("Guest"); //all fine
  }
};
let sayWelcome = welcomeSite;
welcomeSite = null;
sayWelcome(); // WElcome to W3Docs, dear Guest (nested call works here)

As you can see, it worked here. That’s because the name "func" is function-local. It’s not brought from outside. The external code has its variable welcomeSite or sayWelcome.

Summary

So, it can be stated that functions are objects.

In this chapter, we represented the following properties of the functions:

  1. name : it’s the name of the function, as a rule, taken from the function definition. In case there is not any, JavaScript may try to guess it from the context.
  2. length : the arguments’ number in the function definition. Rest parameters are not included.

In case the function is declared as a Function Expression, carrying the name, it is known as a Named Function Expression. It can be used to reference itself, for recursive calls, and more.




Do you find this helpful?

Related articles