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

10-将函数传给函数

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

13.6.2 将函数传给函数

大家已经接触了很多将函数传给函数的例子:比如,把函数传给 setTimeoutforEach 。这样做的另一个原因是为了管理异步编程,作为异步编程的一个范式,它已经越来越流行了。实现异步执行的常见方法是将一个函数(通常叫回调函数,缩写为cb)传给另一个函数。该函数在闭包函数执行完成时(不论它执行了什么操作)被调用(回调)。在第14章中,作者会在更大范围内讨论回调函数。

把一个函数传给另一个函数的用法除了用在回调上,它还是一个“注入”功能的好方法。来看一个叫作 sum 的函数,它会统计一个数组中所有数字的总和(为了简化例子,对于数组中的非数字元素不做任何检查和错误处理)。这是一个很简单的练习,但是如果需要一个返回数字平方和的函数呢?当然,可以简单地编写一个名为 sumOfSquares 的函数……如果还需要立方和呢?这正是传递函数能够起作用的地方。下面看看 sum 函数的实现。

function sum(arr, f) {
   // 如果没有提供任何函数,使用一个将参数原样返回的“空 函数”
   if(typeof f != 'function') f = x => x;
   return arr.reduce((a, x) => a += f(x), 0);
}
sum([1, 2, 3]);                                // 返回 6
sum([1, 2, 3], x => x*x);                      // 返回 14
sum([1, 2, 3], x => Math.pow(x, 3));           // 返回 36

通过给 sum 函数传入一个函数,就可以完成任何想做的事情。需要平方根的和?没问题!需要数字的4.233次方的和?简单!注意,如果不想在调用 sum 函数的时候做任何特别的事情,那就不传入函数。此时,在函数内部,参数f的值是 undefined ,这时如果调用它就会出错。为了防止这种错误,把非函数的参数转换成一个“空函数”,其实就是什么都不做。也就是说,如果传入5,它就返回5,以此类推。也有一些更高效的方式可以处理这种情况(例如,调用另外的函数,这样就节省了在每个元素上调用空函数的开销),但像这样创建“安全”函数是一个不错的实践。