函数是我们程序最重要的组成部分,下面我们就来回顾下函数都有哪些玩法
什么是纯函数
简单来说就是不依赖外部参数的函数:如
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函数实现的原理就是先把参数收集起来,然后再执行
总结
函数是编程语言的灵魂,高阶函数需要我们细细品味才能体会到编程的魅力
最后
关注微信公众号码不停息,交个朋友吧