当前位置:嗨网首页>书籍在线阅读

10-函数表达式和匿名函数

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

6.6 函数表达式和匿名函数

至此,已经详细介绍了函数声明,也就是声明函数体(定义函数做了什么)和标识符(便于后期调用)的地方。JavaScript也支持匿名函数,这种函数没有标识符。

大家可能很好奇一个没有标识符的函数能有什么用。没有标识符,怎么调用它呢?答案就在于理解函数表达式。大家知道一个表达式可以计算值,而函数也可以计算值。函数表达式是声明(基本都没有名字)函数的一种简单方式。函数表达式可以用来赋值(类似给它一个标识符),或者立刻被调用[2]

除了可以省略函数名,函数表达式在语法上跟函数定义是完全一样的。来看这样一个例子,定义一个函数表达式然后把它赋给一个变量(这实际上等效于函数定义):

const f = function() {
    // ...
}; 

这段代码与使用普通方式声明的函数带来的结果是一样的:标识符f可以用来引用函数。和普通的函数声明一样,可以通过 f() 来调用函数。唯一的不同是这里实际上创建了一个匿名函数(通过使用函数表达式)并把它赋给了一个变量。

匿名函数的使用范围很广:可以作为其他函数或方法的参数,还可以用来创建对象的函数属性。将在本书的后面介绍这些用法。

前面提到过在函数表达式中函数名不是必须的...那么当把一个具名的函数赋给一个变量会发生什么呢(以及为什么我们要这么做)?比如:

const g = function f() {
    // ...
}

当一个函数被这样创建时, g 这个名字具有较高的优先级,在引用函数时(在函数外),应该使用 g ;如果使用f引用函数则会得到一个undefined variable的错误。回到这个例子中,如果直接引用f会出错,那么为什么要这样做呢?因为这样就可以在函数内部引用它本身(称为递归调用):

const g = function f(stop) {
    if(stop) console.log('f stopped');
    f(true);
}; 
g(false); 

在函数内部,使用 f 来引用这个函数,在函数外部则用 g 。给一个函数定义两个毫不相关的名字并没有什么特殊原因,只是为了说明函数表达式是如何工作的。

由于函数声明和函数表达式看起来是一样的,大家可能会好奇JavaScript是如何区分它们的(或者它们之间究竟有什么不同)。答案是取决于上下文:如果函数声明作为一个表达式使用,那么它就是函数表达式,否则就是函数声明。

其中的区别大都是理论上的,平时并不需要特别注意这些区别。当定义了一个具名函数并准备之后调用它,大部分时候会想都不想地去声明一个函数,而当需要创建一个函数来赋值或者将其传入其他函数中时,自然会使用函数表达式。