首页 > 编程笔记

JS高阶函数的理解

在 JavaScript 中,如果函数满足以下两点中的任意一点或全部,则这个函数就称为高阶函数(Higher-Order Function):
JavaScript 闭包一文的示例中,increment() 函数就是一个高阶函数,它返回了 by() 函数用于对参数进行自定义步长的自增操作。

JavaScript 数组中的很多函数也都是高阶函数,如 map()、reduce()、filter() 等,这些函数都接收一个函数作为参数,用于对访问的每个数组元素进行一些操作。

对于同时接收函数作为参数并返回新的函数的高阶函数,一般是对参数函数进行增强和组合,然后返回具有新功能的函数。

例如,把任一函数所返回的数字结果进行平方运算,代码如下:
function square(f){
     return(...args)=>f(...args)**2;
}
const sum=(a,b)=>a+b;
const squareOfSum=square(sum);
console.log(squareOfSum(1,2));  //9
代码中的 square() 函数接收任意一个函数f作为参数,然后在 return 语句中,返回了一个新的函数,这个函数使用 rest 运算符接收了一个变长参数 args,它的返回值是调用 f() 函数并进行平方运算的结果。

这里需要注意的是,后边给 f() 传递的 ...args 是扩展(Spread)运算符,与前边的 rest 操作相反,用于把数组元素、对象属性分别赋值给一组变量,通过这种方式就能让 square() 返回的新函数把参数原封不动地传递给原函数 f(),从而在不改变行为的基础上,添加平方运算。

例如示例中的 squareOfSum(1,2) 中的 1 和 2 会传递给 sum() 函数。

接下来,示例代码定义了一个进行加法操作的函数 sum(),对两个数字进行相加,然后调用 square() 函数对 sum() 函数进行包装,这样就形成了一个计算两数之和的平方的函数。

接着给 squareOfSum() 函数传递两个参数 1 和 2,它们分别会传递给 sum() 函数,之后执行 sum(1,2)∗∗2 平方运算,得到了结果 9,后面可以继续使用 squareOfSum() 函数计算其他的数字,因为闭包的特性,sum() 函数已经被 squareOfSum() 捕获了,只需给 squareOfSum() 传递 sum() 所需的参数就可以进行加法操作了,然后计算结果的平方。

使用这种方式,只要计算结果是返回数字类型的函数,都可以通过 square() 函数进行包装,从而在结果的基础上进行平方运算。

例如可以再定义一个计算三数之差的平方的函数,代码如下:
const diff=(a,b,c)=>a-b-c;
const squareOfDiff=square(diff);
console.log(squareOfDiff(9,2,1));  //36
代码的输出结果是 36。这种通过自由地对函数进行组合来创造出不同的业务逻辑是函数式编程的特点。

推荐阅读