理解高阶函数,修炼编程内功

938 阅读2分钟

函数是我们程序最重要的组成部分,下面我们就来回顾下函数都有哪些玩法

什么是纯函数

简单来说就是不依赖外部参数的函数:如

	const num = 2;
    function Fn(arg){
    	return num*arg
    }
    // Fn 不是纯函数
function Fn2(num,arg){
	return num*arg
}
// Fn2 是纯函数,可以使用ES6箭头函数,让函数看起来更加简洁

const Fn2 = (num,arg) => num*arg

纯函数是我们实现高阶函数的基础,我们日常写函数时也应该尽量写纯函数

什么是高阶函数

高阶函数的定义也很简单:参数是一个函数,或者返回一个函数的函数,如下函数都是高阶函数

	function Fn(fn){
    	fn()
    }
    
    function Fn2(){
    	return function(){}
    }

我们经常说的闭包也是高阶函数的一种,如:

	function Fn(){
    	const num = 1;
        function Fn2(){ 
        	console.log(num) // 1
        }
        return Fn2
    }
	

此时,Fn2可以说是个闭包函数,Fn可以说是高阶函数

使用高阶函数封装map方法

我们常见的一些方法如map,every,some,都是ES6给我们封装好的高阶函数,那他们内部都是如果实现的呢?下面我们就模拟实现个map方法

Array.prototype.myMap = function (fn, context) {
  let arr = this;
  let temp = [];
  for (let i = 0; i < arr.length; i++) {
    let result = fn.call(context, arr[i], i, arr)
    temp.push(result)
  }
  return temp
}

测试

const arr = [1, 2, 3, 4]
const arr2 =  arr.myMap(item => {
 	return item + 1
})
// 输出 [2,3,4,5]

使用高阶函数封装once方法

当需要只执行一次的函数时,我们就可以使用高阶函数来实现,如:

function once(fn) {
  let flag = true;
  return function () {
    if (flag) {
      fn()
      flag = false
    } else {
      console.log('已经执行过了哦')
    }
  }
}
function dome() {
  console.log('我要执行')
}
const d = once(dome)
d()
d()
/*
我要执行
已经执行过了哦
*/

函数柯里化

柯里化是把一个多参数函数转化成一个嵌套的一元函数的过程,从功能上说,它实现了函数功能的细化。 下面我们先简单实现一个柯里化函数

	let Fn = (x,y)=>x+y
    // 使用Fn函数
    Fn(1,2) // 3

把Fn柯里化

let Fn = (x, y) => x + y;
const curry = (fn) => {
  return (x) => {
    return (y) => {
      return fn(x, y);
    };
  };
};
const fn = curry(Fn);
fn(1)(2);  // 3

可以看见,我们在使用fn函数的时候可以单个传递参数,这样更利于函数的解耦,下面我们来封装一个通用的柯里化函数,这样不管我们的参数有几个,都可以变成单一参数

const curry = function (fn) {
  return function curriedFn(...args) {
    if (args.length < fn.length) {
      return function () {
        return curriedFn(...args.concat([...arguments]));
      };
    }
    return fn(...args);
  }
}

我们使用curry

const fn = (x, y, z, a) => x + y + z + a;
const myfn = curry(fn);
console.log(myfn(1)(2)(3)(1)); // 7

curry函数实现的原理就是先把参数收集起来,然后再执行

总结

函数是编程语言的灵魂,高阶函数需要我们细细品味才能体会到编程的魅力

最后

关注微信公众号码不停息,交个朋友吧