JS高阶编程技巧--compose函数
先看代码:
let fn1 = function (x) {
return x + 10;
};
let fn2 = function (x) {
return x * 10;
};
let fn3 = function (x) {
return x / 10;
};
这是几个简单的运算方法,但想输出的是一个多层函数嵌套的运行结果,即把前一个函数的运行结果赋值给后一个函数,当然我们可以写成一下这样:
let x = fn1(6);
x = fn2(x);
x = fn1(x);
x = fn3(x);
但现在我就想用一个函数解决这种问题,形如:
compose(fn1, fn2, fn1, fn3)(6);
这个compose函数就是这篇文章介绍的——函数调用的扁平化,即把层级嵌套的那种函数调用(一个函数的运行结果当作实参传给下一个函数的这种操作)扁平化,这就是compose函数。
那么下面就是开始实现这个函数:
首先我们看参数,需要给出不确定个数的函数:
function compose(...funcs) {
//=>funcs:传递的函数集合
}
compose函数执行后跟个(),说明函数执行完再执行一个函数,即函数执行完会返回一个新函数,而且也会给出第一次调用函数时的参数:
function compose(...funcs) {
//=>funcs:传递的函数集合
return function proxy(...args) {
//=>args:第一次调用函数传递的参数集合
}
}
继续往下进行,我们需要判断给出的函数集合的个数,如果没有给函数,我们只需将后一个的参数返回,如果只给出一个函数,我们只需把后一个的参数赋给这个函数去执行即可:
function compose(...funcs) {
//=>funcs:传递的函数集合
return function proxy(...args) {
//=>args:第一次调用函数传递的参数集合
let len = funcs.length;
if (len === 0) {
//=>一个函数都不需要执行,直接返回ARGS
return args;
}
if (len === 1) {
//=>只需要执行一个函数,把函数执行,把其结果返回即可
return funcs[0](...args);
}
};
}
如果给出的参数集合是两个及以上,那就是把前一个函数的执行结果赋给后一个函数,说到这,应该会想到一个满足这个需求的数组方法——reduce:
function compose(...funcs) {
//=>funcs:传递的函数集合
return function proxy(...args) {
//=>args:第一次调用函数传递的参数集合
let len = funcs.length;
if (len === 0) {
//=>一个函数都不需要执行,直接返回ARGS
return args;
}
if (len === 1) {
//=>只需要执行一个函数,把函数执行,把其结果返回即可
return funcs[0](...args);
}
return funcs.reduce((x, y) => {
});
};
}
但这里需要注意的是,第一次执行的时候,参数x是个函数,之后再执行的时候x是个函数执行的结果,所以需要进行判断:
function compose(...funcs) {
//=>funcs:传递的函数集合
return function proxy(...args) {
//=>args:第一次调用函数传递的参数集合
let len = funcs.length;
if (len === 0) {
//=>一个函数都不需要执行,直接返回ARGS
return args;
}
if (len === 1) {
//=>只需要执行一个函数,把函数执行,把其结果返回即可
return funcs[0](...args);
}
return funcs.reduce((x, y) => {
return typeof x === "function" ? y(x(...args)) : y(x)
});
};
}
这样,compose函数完成。
当然,redux源码中的compose.js也可以实现一开始想要的效果:
export default function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
但它和我们写的compose函数有些不同,它执行的顺序是函数集合中的函数从后往前执行,所以结果也会不同:
compose(fn1, fn2, fn1, fn3)(6)); //=> 用第一个compose执行的结果是17,用redux的执行结果是116
JS高阶编程技巧--compose函数的更多相关文章
- JS高阶编程技巧--惰性函数
在vue.react等框架大量应用之前,我们需要使用jQuery或者原生js来操作dom写代码,在用原生js进行事件绑定时,我们可以应用DOM2级绑定事件的方法,即:元素.addEventListen ...
- JS高阶编程技巧--柯理化函数
首先看一段代码: let obj = { x: 100 }; function fn(y) { this.x += y; console.log(this); } 现在有一个需求:在1秒后,执行函数f ...
- JS高阶函数的理解(函数作为参数传递)
JS高阶函数的理解 高阶函数是指至少满足下列条件之一的函数. · 函数可以作为参数被传递 · 函数可以作为返回值输出 一个例子,我们想在页面中创建100个div节点,这是一种写法.我们发现并不是所有用 ...
- React.js高阶函数的定义与使用
/* 高阶函数的简单定义与使用 一: 先定义一个普通组件 二: 用function higherOrder(WrappendComponent) { return } 将组件包裹起来,并用export ...
- js 高阶函数 闭包
摘自 https://www.cnblogs.com/bobodeboke/p/5594647.html 建议结合另外一篇关于闭包的文章一起阅读:http://www.cnblogs.com/bob ...
- js高阶函数
我是一个对js还不是很精通的选手: 关于高阶函数详细的解释 一个高阶函数需要满足的条件(任选其一即可) 1:函数可以作为参数被传递 2:函数可以作为返回值输出 吧函数作为参数传递,这代表我们可以抽离一 ...
- js高阶函数应用—函数防抖和节流
高阶函数指的是至少满足下列两个条件之一的函数: 1. 函数可以作为参数被传递:2.函数可以作为返回值输出: javaScript中的函数显然具备高级函数的特征,这使得函数运用更灵活,作为学习js必定会 ...
- js高阶函数应用—函数柯里化和反柯里化
在Lambda演算(一套数理逻辑的形式系统,具体我也没深入研究过)中有个小技巧:假如一个函数只能收一个参数,那么这个函数怎么实现加法呢,因为高阶函数是可以当参数传递和返回值的,所以问题就简化为:写一个 ...
- 浅谈JS高阶函数
引入 我们都知道函数是被设计为执行特定任务的代码块,会在某代码调用它时被执行,获得返回值或者实现其他功能.函数有函数名和参数,而函数参数是当调用函数接收的真实的值. 今天要说的高阶函数的英文为High ...
随机推荐
- maven版本对应的jdk
今天配置项目环境发现jdk1.6与maven-3.39不能匹配 查询jdk与maven的版本对应关系 关系网址:http://maven.apache.org/docs/history.html Ma ...
- es7中数组如何判断元素是否存在
const arr = [1,2,3,4,5,6] console.log(arr.includes(4)) //true
- Spring加载早期获取BasePackage
public class GetBasePackage { private Class<? extends Annotation> annotation; public GetBasePa ...
- java小心机(4)| 继承与组合的爱恨情仇
在java中,有两种主要复用代码的方法:继承和组合. 继承,是OOP的一大特性,想必大家都非常熟悉了;组合,其实也很常见,只是不知道它的名字罢了. 继承 子类拥有父类的基本特性,需使用extend关键 ...
- Python错误与异常
1 异常和错误 1.1 错误和异常 从软件方面来说,错误是语法或者逻辑上的,语法错误指示软件的结构上有错误,导致不能被解释器解释.当程序的语法正确后,剩下的就是逻辑错误了,逻辑错误可能是由于不完整或者 ...
- robotframework,移动端(小程序)自动化,解决无法输入中文
1.如何输入中文 方法: 在open application参数最后,新增unicodeKeyboard=True resetKeyboard=True:不加入这两个参数时,中文无法输入
- python HelloWorld 的 4 种姿势,你知道几种
安装完 Python 之后该干啥,当然是要 say HelloWorld 了. python.exe 就是个普通程序 和其它所有命令一样,在命令行中敲下 python 并回车的时候,操作系统去 PAT ...
- js解析json时报:Unexpected token s in JSON at position 0
原因肯定是返回的json格式有问题 最有可能是后台在程序执行过程中,输出了某些调试信息等等,这些输出的字符串和json拼接成了新的字符串来解析,这时就会报错: 比如我在入口文件里var_dump了__ ...
- 关于基本布局之——Flex布局
Flex布局 1.Flex为"Flexible Box"的简称,即为弹性布局,可作用于任何容器上.给div这类块状元素元素设置display:flex或者给span这类内联元素设置 ...
- Vmware14 开机黑屏或者以独占方式锁定此配置文件失败等问题解决办法
把VMware14版本卸载掉,然后重装一个12版本的 打开之前创建的虚拟机,提示版本不兼容, 打开配置文件: 修改版本为重装的版本,比如12 然后编辑虚拟机设置指定一个系统,比如centos,即可 就 ...