Menu Close

JavaScript 匿名函数 ( 函数表达式)

JavaScript 中,函数不是一种“神奇的语言结构”,而是一种特殊的值。

JavaScript 匿名函数 ( 函数表达式)
JavaScript 匿名函数 ( 函数表达式)

我们之前使用的语法称为函数声明(Function Declaration):

function sayHi() {
  alert( "Hello" );
}

还有一种创建函数的语法,称为函数表达式(Function Expression)。

JavaScript 匿名函数简介

匿名函数是没有名称的函数。它允许我们在任何表达式中间创建一个新函数。下面展示了如何定义一个简单的匿名函数:

例如:

let sayHi = function() {
  alert( "Hello" );
};

在这里,我们可以看到变量 sayHi 获取了一个值——一个通过 function() { alert("Hello"); } 创建的新函数。

由于函数是在赋值表达式的上下文中创建的(等号右侧),因此这是一个函数表达式(Function Expression)。请注意,如果您不将匿名函数放在 () 中,则会出现语法错误。() 使匿名函数成为返回函数对象的表达式。

匿名函数在创建后不可访问。因此,您经常需要将其分配给一个变量。请注意,function 关键字后面没有函数名。对于函数表达式来说,省略名称是允许的。

我们在这里立即将它赋值给变量,因此这些代码的含义是一样的:“创建一个函数,并将其放入变量 sayHi 中”。

在我们稍后会遇到的一些更高级的场景中,函数可能会被创建后立即调用,或者被安排稍后执行,而不会被存储到任何地方,因此保持匿名。这样的函数,成为匿名函数。

函数是一个值

让我们再强调一遍:无论函数是如何创建的,函数本质上都是一个值。上面两个示例都将函数存储在变量 sayHi 中。

我们甚至可以使用 alert 打印出这个值:

function sayHi() {
  alert( "Hello" );
}

alert( sayHi ); // shows the function code

请注意,最后一行并不会执行函数,因为 sayHi 后面没有括号。有些编程语言中,提到函数名就会自动执行函数,但 JavaScript 并不是这样。

JavaScript 中,函数是一个值,因此我们可以像处理其他值一样处理它。上面的代码展示的是函数的字符串表示形式,也就是它的源代码。

当然,函数是一种特殊的值,因为我们可以像这样调用它:sayHi()

但它依然是一个值,所以我们可以像对待其他类型的值一样使用它。

我们可以将一个函数复制到另一个变量中:

function sayHi() {   // (1) create
  alert( "Hello" );
}

let func = sayHi;    // (2) copy

func(); // Hello     // (3) run the copy (it works)!
sayHi(); // Hello    //     this still works too (why wouldn't it)

上面的代码详细说明如下:

  1. 第 (1) 行是函数声明,它创建了一个函数,并将其放入名为 sayHi 的变量中。

  2. 第 (2) 行将这个函数复制到变量 func 中。再次注意:sayHi 后面没有括号。如果加了括号,比如 func = sayHi(),那么 func 得到的将是 sayHi() 的返回结果,而不是函数本身。

  3. 现在我们可以通过 sayHi()func() 来调用这个函数。

我们也可以在第一行使用函数表达式来声明 sayHi

let sayHi = function() { // (1) create
  alert( "Hello" );
};

let func = sayHi;  //(2)
// ...

一切都会照常运行。

为什么需要分号?

你可能会想,为什么函数表达式(Function Expressions)末尾有分号 ;,而函数声明(Function Declarations)没有:

function sayHi() {
  // ...
}

let sayHi = function() {
  // ...
};

答案很简单:函数表达式是在赋值语句中创建的,形式为 function(…) {…},例如 let sayHi = …;。分号 ; 是语句结尾的推荐写法,它不是函数语法的一部分。

对于更简单的赋值,比如 let sayHi = 5;,也需要分号,函数赋值时同样需要分号。

回调函数

让我们来看更多将函数作为值传递并使用函数表达式的示例。

我们将编写一个名为 ask(question, yes, no) 的函数,带有三个参数:

  • question:问题的文本

  • yes:如果回答是“是”,执行的函数

  • no:如果回答是“否”,执行的函数

这个函数应该提出问题,并根据用户的回答,调用 yes()no()

function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

function showOk() {
  alert( "You agreed." );
}

function showCancel() {
  alert( "You canceled the execution." );
}

// usage: functions showOk, showCancel are passed as arguments to ask
ask("Do you agree?", showOk, showCancel);

在实践中,这种函数非常有用。现实生活中的询问与上面的例子之间的主要区别在于,现实生活中的函数使用比简单的确认框更复杂的方式与用户交互。在浏览器中,这类函数通常会显示一个漂亮的提问窗口。但那是另一个话题。

ask 函数的 showOkshowCancel 参数被称为回调函数(callback functions)或简称回调。

其思路是我们传递一个函数,并期望在必要时它能“回调”我们。在我们的例子中,showOk 是“是”答案的回调,showCancel 是“否”答案的回调。

我们可以使用函数表达式来编写一个等效的、更简短的函数:

function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

ask(
  "Do you agree?",
  function() { alert("You agreed."); },
  function() { alert("You canceled the execution."); }
);

wer

除教程外,本网站大部分文章来自互联网,如果有内容冒犯到你,请联系我们删除!
Posted in JavaScript 基础

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Leave the field below empty!