Function object, NFE
JavaScript Function object, NFE (JavaScript函数对象, NFE)
In the previous chapters, we have already learned that functions in JavaScript are values. Also, each JavaScript value has a type. (在前面的章节中,我们已经了解到JavaScript中的函数是值。此外,每个JavaScript值都有一个类型。)
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). (函数是JavaScript中的对象。不仅可以调用对象,还可以将它们作为对象处理(添加或删除属性、通过引用传递等)。)
The Property “name”
The Property “name” (“name”属性)
The function objects consist of usable properties. It’s demonstrated in the example below:
function welcomeSite() {
console.log("Welcome to w3cdoc");
}
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 w3cdoc");
};
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
The “length” Property (“length”属性)
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. (有时,您可以使用length属性来反思在其他函数上运行的函数。)
Custom Properties
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 w3cdoc");
welcomeSite.counter++; // let's count how many times we run
}
welcomeSite.counter = 0; // initial value
welcomeSite(); // Welcome to w3cdoc
welcomeSite(); // Welcome to w3cdoc
welcomeSite(); // Welcome to w3cdoc
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. (请考虑属性不是变量。因此,属性计数器和let counterlet计数器变量不能相互关联。)
A function can be treated as an object, store properties, but it won’t affect its execution. (函数可以被视为对象,存储属性,但不会影响其执行。)
Named Function Expression
Named Function Expression (命名函数表达式)
The Named Function Expression (NFE) is for the Function Expressions having a name. (命名函数表达式(NFE)用于具有名称的函数表达式。)
An ordinary Function Expression looks like this:
let welcomeSite = function (user) {
console.log(`Welcome to w3cdoc, dear ${user}`);
};
You can add a name to it:
let welcomeSite = function func(user) {
console.log(`Welcome to w3cdoc, 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. (请注意,在函数后添加名称“func”无法将其转换为函数声明,因为它是赋值表达式的一部分。)
The function remains as follows:
let welcomeSite = function func(user) {
console.log(`Welcome to w3cdoc, dear ${user}`);
};
welcomeSite("David"); // Welcome to w3cdoc, dear David
The name “func” allows the function referencing itself internally. Moreover, there is no possibility of seeing it outside of the function. (名称“func”允许函数在内部引用自身。此外,不可能在函数之外看到它。)
Let’s see the example below:
let welcomeSite = function func(user) {
if (user) {
console.log(`Welcome to w3cdoc, dear ${user}`);
} else {
func("Guest"); // use func to re-call itself
}
};
welcomeSite(); // Welcome to w3cdoc, 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. (在这种情况下,如果未提供用户,则welcomeSite函数使用“Guest”调用自身。)
In a variety of cases, you can act like this:
let welcomeSite = function (user) {
if (user) {
console.log(`Welcome to w3cdoc, 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 w3cdoc, 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 . (发生这种情况是因为函数从外部词法环境获取welcomeSite。不存在本地welcomeSite。因此,使用外部变量。因此,在调用过程中,外部welcomeSite可能会变为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 w3cdoc, dear ${user}`);
} else {
func("Guest"); //all fine
}
};
let sayWelcome = welcomeSite;
welcomeSite = null;
sayWelcome(); // WElcome to w3cdoc, 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. (如你所见,它在这里起作用了。这是因为名称“func”是功能本地的。不是从外面带来的。外部代码具有其变量welcomeSite或sayWelcome。)
Summary
Summary (概要)
So, it can be stated that functions are objects. (因此,可以说函数是对象。)
In this chapter, we represented the following properties of the functions:
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. 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. (如果函数被声明为携带名称的函数表达式,则称为命名函数表达式。它可用于引用自身、递归调用等。)