compose组合函数
在函数式编程当中有一个很重要的概念就是函数组合, 实际上就是把处理数据的函数像管道一样连接起来, 然后让数据穿过管道得到最终的结果。 例如:
const add1 = (x) => x + 1;
const mul3 = (x) => x * 3;
const div2 = (x) => x / 2;
div2(mul3(add1(add1(0)))); //=>3
而这样的写法可读性明显太差了,我们可以构建一个compose函数,它接受任意多个函数作为参数(这些函数都只接受一个参数),然后compose返回的也是一个函数,达到以下的效果:
const operate = compose(div2, mul3, add1, add1)
operate(0) //=>相当于div2(mul3(add1(add1(0))))
operate(2) //=>相当于div2(mul3(add1(add1(2))))
简而言之:compose可以把类似于f(g(h(x)))这种写法简化成compose(f, g, h)(x),请你完成 compose函数的编写
//for循环
const compose=function compose(...funcs){
return function operate(x){
let len=funcs.length
if(len===0)return x
if(len===1)return funcs[0](x)
for(let i=len-1;i>=0;i--){
const func=funcs[i]
x=func(x)
}
return x
}
}
//解决方案1
const compose=function compose(...funcs){
return function operate(x){
let len=funcs.length
if(len===0)return x
if(len===1)return funcs[0](x)
return funcs.reduceRight((prev,func)=>func(prev),x)
}
}
// 解决方案二:redux中提供的compose函数
const compose = function compose(...funcs) {
if (funcs.length === 0) return arg => arg
if (funcs.length === 1) return funcs[0]
return funcs.reduce((a, b) => x => a(b(x)))
}
柯里化函数
创建一个闭包,把一些信息(可能是传递进来的实参。也可能是闭包中自己处理的值)先“保存”起来,用来供其“下级上下文中”去使用===>JS高阶编程技巧:柯里化函数思想 但是此高阶技巧不能滥用,因为基于闭包存储,会产生不释放的内存,用的多了,内存消耗较大,项目性能会变慢;我们应该合理使用闭包,而且需要手动把不用的内存释放掉
//写出代码实现以下效果
const fn = function fn() {
...
}
let res = fn(1, 2)(3)
console.log(res) //=>6 1+2+3
const fn = function fn(...params) {
// params:[1, 2]
return function anonymous(...args) {
// args:[3]
params = params.concat(args) //[1, 2, 3]
return params.reduce((prev, item) => prev + item)
}
}
//这样写可读性太差 可以改为下面那种箭头函数
const fn = (...params) => (...args) => params.concat(args).reduce((prev, item) => prev + item)
let res = fn(1, 2)(3)
console.log(res) //=>6 1+2+3
const fn = (...params) => {
return (...args) => {
params = params.concat(args)
return params.reduce((prev, item) => {
return prev + item
})
}
}
//写出代码实现以下效果
let res = curring()(1)(2)(3)
console.log(+res) //->6
res = curring()(1, 2, 3)(4)
console.log(+res) //->10
res = curring()(1)(2)(3)(4)(5)
console.log(+res) //->15
const curring = () => {
let params = []
const add = (...args) => {
// 闭包中的params用来存储每一次执行add函数,传递的实参值
params = params.concat(args)
return add
}
add.toString = () => {
return params.reduce((prev, item) => {
return prev + item
})
}
return add
}
// 获取的res是add函数
// + 在谷歌老版本浏览器中,基于 console.log 输出函数,会先调用函数的 toString 方法,此方法的返回值,就是在控制台要输出的结果
// + 新版本浏览器不再具备这个机制,输出的值都是函数本身;所以我们在前面设置一个“+”,目的是把函数对象转为数字「Symbol.toPrimitive -> valueOf -> toString -> 转数字」;这样们只需要重写相应的方法,让其把传递的实参就和即可!!
数组中的9大迭代方法
支持callback,迭代数组中的每一项,每迭代一次,都会把callback执行一次… callback中会接收到item:当前迭代项 index:当前迭代项索引
- forEach
- map
- filter 按条件[callback返回的结果(true/false)]进行筛选,把符合条件的放在新的数组中,原始数组不变 ```javascript let arr=[10,20,30,40,50] //需求:按条件筛选需要的内容 let res=arr.filter((item,index)=>{ return item>30//=>[40,50] }) console.log(res)
//需求:删除30这一项 let index=arr.indexOf(30) arr.splice(index,1) console.log(arr) //===================================================================== arr=arr.filter(item=>item!==30) console.log(arr)
- [ES6] find 按条件查找数组中的“某一项”[即使多项符合条件,查找到的只有第一项]
- [ES6] findIndex 按条件查找数组中“某一项的索引”
- some 验证数组中的“某一项”是否符合条件,只要有一项符合,some的执行结果就是true [something]
- every 验证数组中的“所有项”是否符合条件,只有所有项都符合条件,every执行结果才是true [everyone]
```javascript
let arr=[{
name:'张三',
age:25
},{
name:'李思',
age:27
},{
name:'王五',
age:22
}]
console.log(
arr.some(item=>item.age>=30)
)//false
- reduce/reduceRight 依次迭代数组每一项(reduceRight是反着迭代),但是其可以把上一次callback处理的结果,传递到下一个callback执行中,这样可以实现结果的“累计” ```javascript let arr=[10,20,30,40,50] let res=arr.reduce((prev,item,index)=>{ / 第一轮prev=10 item=20 index=1 —>30[把数组第一项作为prev的初始值,数组从第二项开始迭代] 第二轮prev=30 item=30 index=2 —>60[prev获取的是上一轮callback执行的返回值] 第三轮prev=60 item=40 index=3 —>100 第四轮prev=100 item=50 index=4 —>150 迭代结束,最后一轮处理的结果会作为reduce函数的总返回值 / return prev+item })
let res=arr.reduce((prev,item,index)=>{ / 第一轮prev=100 item=10 index=0 —>110[数组从第一项开始迭代] …… / return prev+item },100)//第二个参数就是在给第一轮迭代的prev赋值初始值 ```
拓展(版本号)
:::info 一个语言规范的升级
- stage-0
- stage-1
- stage-2
- stage-3 草案阶段「可以使用了」
正式发版
::: :::info 一个插件/框架/库的升级开发
- alpha 内测 3.0.0-alpha.0~3.0.0-alpha.13
- beta 公测 [和正式发版的内容出入就很小了] 3.0.0-beta.1 ~ 3.0.0-beta.24
- rc预发版本 3.0.0-rc.1 ~ 3.0.0-rc.13
- stable 正式发版 3.0.0
:::