Function Expressions
JavaScript Function Expressions (JavaScript函数表达式)
There are two different ways of creating functions in JavaScript. We can use function declaration and function expression. The difference between them is the function name, which can be omitted in function expressions to create anonymous functions. (在JavaScript中创建函数有两种不同的方式。我们可以使用函数声明和函数表达式。它们之间的区别是函数名称,可以在函数表达式中省略以创建匿名函数。)
Here is the syntax for Function Declaration:
function welcome() {
console.log("Welcome to w3cdoc!");
}
welcome();
And this is the syntax for Function Expression:
let welcome = function () {
console.log("Welcome to w3cdoc!");
};
welcome();
The function is assigned to the variable, like any other value no matter how the function is defined because it is just a value stored in the variable welcome. (函数被分配给变量,就像任何其他值一样,无论函数是如何定义的,因为它只是存储在变量welcome中的值。)
We can also show that value using console.log:
function welcome() {
console.log("Welcome to w3cdoc");
}
console.log(welcome); // it shows code of the function
welcome();
The last line does not run the function, as there are no parentheses after welcome. (>最后一行不运行函数,因为welcome后面没有括号。)
JavaScript is not like the programming languages where any mention of a function name causes its execution. In JavaScript, a function is a value and we can deal with it as a value. The code in the example above shows its string representation, which is the source code. (JavaScript与编程语言不同,在编程语言中,任何提及函数名称都会导致其执行。在JavaScript中,函数是一个值,我们可以将其作为一个值处理。上面示例中的代码显示了其字符串表示形式,即源代码。)
A function is a special value, we can call it like welcome(). It is still a value and we can work with it the way we work with other values. (函数是一个特殊值,我们可以将其称为welcome ()。它仍然是一种价值观,我们可以像使用其他价值观一样使用它。)
We can even copy a function to another variable like this:
function welcome() { // (1) create the function
console.log("Welcome to w3cdoc");
}
let anotherFunc = welcome; // (2) copy
anotherFunc(); // Welcome to w3cdoc //it works
welcome(); // Welcome to w3cdoc // this works too
Let’s discuss what happens above in detail:
The Function Declaration (1) creates the function putting it into the variable named welcome. Line (2) copies the variable welcome into the variable anotherFunc. It is possible to call the function as both welcome() and anotherFunc(). (函数声明(1)创建函数,将其放入名为welcome的变量中。 第(2)行将变量welcome复制到变量anotherFunc中。 可以将函数同时调用为welcome ()和anotherFunc ()。)
If we have used a Function Expression to declare welcome, in the first line nothing would change:
let welcome = function () {
console.log("Welcome to w3cdoc");
};
let anotherFunc = welcome;
anotherFunc();
A semicolon at the end
A semicolon at the end (末尾有一个分号)
You can ask, why Function Expression has a semicolon at the end, but Function Declaration does not:
function welcome() {
// ...
}
let welcome = function () {
// ...
};
The reason is there’s no need for semicolons at the end of code blocks and syntax structures that use them as if { … }, for { }, function f { }, and so on.
A Function Expression can be used inside the statement: let welcome = …;, as a value, but not a code block. It is recommended to put the semicolon at the end of statements, no matter what the value is. That is why the semicolon here is not related to the Function Expression itself.
Callback functions
Callback functions (回调函数)
A function passed to another function is called a “callback” in JavaScript. (传递给另一个函数的函数在JavaScript中称为“回调”。)
There are examples of passing functions as values and using function expressions presented below. (下面提供了将函数作为值传递和使用函数表达式的示例。)
The function should ask the siteQuestion and call answerYes() or answerNo() depending on the user’s answer:
function callbackFunc(siteQuestion, answerYes, answerNo) {
if (confirm(siteQuestion)) {
answerYes()
(answerYes ())
} else {
answerNo();
}
}
function chooseOk() {
console.log("It’s great.");
}
function chooseCancel() {
console.log("Try again");
}
// use answerOk, answerCancel functions passed as arguments to the request
callbackFunc("Are you familiar with JS function decalarations?", chooseOk, chooseCancel);
In practice, these kinds of functions are quite useful. The main difference between a real-life callbackFunc and the example above is that real-life functions use more difficult ways to interact with the user than a simple confirm. (在实践中,这些功能非常有用。现实生活中的callbackFunc和上面的示例之间的主要区别在于,现实生活中的函数使用比简单的确认更难的方式与用户交互。)
We call the arguments chooseOk and chooseCancel of asking callback functions or callbacks. (>我们调用参数chooseOk和chooseCancel询问回调函数或回调。)
We pass a function expecting that it will be “called back” later if necessary. In this case, chooseOk becomes the callback for “yes” answer, and chooseCancel for “no”. (我们传递一个函数,希望在必要时稍后将其“回调”。在这种情况下,选择“确定”将成为“是”答案的回调,选择“取消”将成为“否”。)
We can use Function Expressions if we want to write the same function much shorter:
function callbackFunc(siteQuestion, answerYes, answerNo) {
if (confirm(siteQuestion)) {
answerYes();
} else {
answerNo();
}
}
callbackFunc(
"Are you familiar with JS function declarations?",
("您熟悉JS函数声明吗?",)
function () {
console.log("It’s great.");
},
function () {
console.log("Try again");
}
);
Functions are declared inside the callbackFunc(…) call and they have no name, which is why they are called anonymous. These kinds of functions are not accessible outside of callbackFunc. This kind of code appears in our scripts very naturally. (函数在callbackFunc (…)调用中声明,它们没有名称,这就是为什么它们被称为匿名函数。这些类型的函数在callbackFunc之外不可访问。这种代码非常自然地出现在我们的脚本中。)
A function is a value that represents an “action”. (>函数是表示“操作”的值。)
Structured values like strings or numbers represent the data. A function can be considered an action. We can proceed between variables and run when we want. (字符串或数字等结构化值表示数据。一个函数可以被认为是一个动作。我们可以在变量之间继续,并在需要时运行。)
Function Expression and Function Declaration
Function Expression and Function Declaration (函数表达式和函数声明)
The main difference between Function Declarations and Expressions is the syntax. (函数声明和表达式之间的主要区别在于语法。)
Function Expression defines a function, created inside an expression or another syntax construct. The presented function is created at the right side of the “assignment expression” = (函数表达式定义在表达式或其他语法构造中创建的函数。呈现的函数创建在“赋值表达式”的右侧=)
// Function Expression
let sum = function (a, b) {
return a + b;
};
A Function Expression works almost the same way as a function declaration or a function statement, the only difference is that a function name is not started in a function expression. The function expressions run as soon as they are defined. (函数表达式的工作方式与函数声明或函数语句几乎相同,唯一的区别是函数名称未在函数表达式中启动。函数表达式在定义后立即运行。)
Function Declaration defines a named function, declared as a separate statement, in the main code flow. Just as Variable Declaration must start with “var”, Function Declaration must start with “function”. (函数声明在主代码流中定义了一个命名函数,声明为单独的语句。正如变量声明必须以“var”开头一样,函数声明必须以“function”开头。)
// Function Declaration
function sum(a, b) {
return a + b;
}
The more delicate difference between the functions is when a function is created by the JavaScript engine. (函数之间更微妙的区别在于JavaScript引擎创建的函数。)
A Function Expression is created when the implementation reaches it and can be used only from that moment. (>函数表达式在实现到达时创建,并且只能从那一刻开始使用。)
Once the execution flow passes to the right side of the assignment let sum = function…, the function is created and can be used. (一旦执行流程传递到赋值的右侧, let sum = function… ,函数就被创建并可以使用。)
Function Declarations are different. (>函数声明不同。)
Function Declarations can be called earlier than they are defined. For instance, no matter where a global Function Declaration is, it is visible in the whole script. The reason is the internal algorithm. (函数声明可以在定义之前提前调用。例如,无论全局函数声明在哪里,它在整个脚本中都是可见的。原因是内部算法。)
When all Function Declarations are processed, the code is executed and has access to these functions. (处理完所有函数声明后,代码将被执行并有权访问这些函数。)
For instance, this works:
welcome("w3cdoc"); // Welcome to w3cdoc
function welcome(siteName) {
console.log(`Welcome to, ${siteName}`);
}
But it would not work If it was a Function Expression:
welcome("w3cdoc"); // error!
let welcome = function (siteName) { // (*) there is no more magic
console.log(`Welcome to ${siteName}`);
};
Function Expressions will be created when the implementation reaches them, which would happen only in the line (). (函数表达式将在实现到达它们时创建,这只会发生在()行中。)
One more special attribute of Declaration is its block scope. (声明的另一个特殊属性是其块范围。)
When a Function Declaration is in a code block in strict mode, it will be visible everywhere inside that block, but not outside of it. (>当函数声明在严格模式下位于代码块中时,它将在该块内的任何地方可见,但不会在其外部可见。)
For example, let’s suppose that we need to declare a function welcome() depending on the age variable that we get during runtime, then we plan to use it later. (例如,假设我们需要声明一个函数welcome () ,这取决于我们在运行时获得的age变量,然后我们计划稍后使用它。)
If we use Function Declaration in strict mode, it won’t work as planned:
"use strict"
let number = prompt("Guess the number", "");
// conditionally declare a function
if (number == 10) {
function guessNumber() { // A function declaration is available everywhere
console.log("it’s right!"); //in the block where it is declared.
}
} else {
function guessNumber() {
console.log("it’s wrong!");
}
}
//we cannot see function declarations inside them,
//because here we have left the braces
guessNumber(); // Error: guessNumber is not defined
What can we do for making welcome visible outside of if? (我们可以做些什么来让欢迎在if之外可见?)
The best proposal would be to use a Function Expression and assign welcome to the variable that is declared outside of if. (最好的建议是使用函数表达式,并将welcome赋值给在if之外声明的变量。)
This code works as planned:
"use strict"
let number = prompt("Guess the number", "");
let guessNumber;
// conditionally declare a function
if (number == 10) {
guessNumber = function () {
console.log("it’s right!");
}
} else {
guessNumber = function () {
console.log("it’s wrong!");
}
}
guessNumber(); // now it’s work
But we could also simplify it using a question mark operator ?:
let number = prompt("Guess the number", "");
let guessNumber = (number == 10) ?
function () {
console.log("it’s right!");
} :
function () {
console.log("it’s wrong!");
};
guessNumber(); // it’s work
When to choose Function Declaration against Function Expression?
When to choose Function Declaration against Function Expression? (何时针对函数表达式选择函数声明?)
When we need to declare a function, Function Declaration syntax is the first to consider. With it, we are free to organize our code the way we want because we can call such functions before they are declared. (当我们需要声明函数时,首先要考虑函数声明语法。有了它,我们可以自由地按照我们想要的方式组织我们的代码,因为我们可以在声明这些函数之前调用它们。)
One more advantage is readability, as it’s easier to look up function f(…) {…} in the code than let f = function(…) {…};. Function Declarations are more impressive. But we need to use Function Declaration in case we need a conditional declaration.