柯里化是什么

目录

1、柯里化 (Currying)

2、柯里化函数的应用:  _.curry(func) 

3、柯里化总结

4、函数组合(compose)

5、Lodash 组合函数

6、函数组合调试

7、Lodash的fp模块

8、PointFree


1、柯里化 (Currying)

当一个函数有多个参数的时候先传递一部分参数调用它(这部分参数以后永远不变)

然后返回一个新的函数接收剩余的参数,返回结果

        下图示例是普通函数与柯里化函数(纯函数)的对比

//普通的函数
function checkAge (min,age) {
    return age >= min
}

console.log(checkAge(18,20));
console.log(checkAge(18,24))

//高进阶纯函数(避免重复的18硬编码)
function checkAge(min){
    return function(age){
        return age >= min
    }
}

//es6写法
//let checkAge = min => (age => age >= min);

let checkAge18 = checkAge(18);
let checkAge20 = checkAge(20);

console.log(checkAge18(20));//true
console.log(checkAge18(24))//true

2、柯里化函数的应用:  _.curry(func) 

功能:创建一个函数,该函数接收一个或多个 func 的参数,如果 func 所需要的参数都被提供则执行 func 并返回执行的结果。  否则继续返回该函数并等待接收剩余的参数

参数:需要柯里化的函数

//lodash中的柯里化函数 curry 使用 ,将多个函数变为一元函数
const _ = reuqire('lodash');

function getSum (a, b, c) {
    return a + b + c
}

const curried = _.curry(getSum);

console.log(curried(1, 2, 3));//6
console.log(curried(1)(1, 3));//6
console.log(curried(1, 2)(3))//6

//模拟curry

function curry(func){
    return function curriedFn(...args){ //表示传入的实参
        if(args.length < func.length){ //实参是否小于形参
            return function(){
            //Array.from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组。
            //参考此博客:https://www.cnblogs.com/jf-67/p/8440758.html
                return curriedFn(...args.concat(Array.from(arguments)))//将arguments伪数组转换成数组
            }
        }
        return func(...args)
    }
}

const curried1 = curry(getSum);

console.log(curried1(1, 2, 3));//6
console.log(curried1(1)(1, 3));//6
console.log(curried1(1, 2)(3))//6

3、柯里化总结

柯里化可以让我们给一个函数传递较少的参数得到一个已经记住了某些固定参数的新函数

这是一种对函数参数的'缓存'

让函数变的更灵活,让函数的粒度更小

可以把多元函数转换成一元函数,可以组合使用函数产生强大的功能

4、函数组合(compose)

如果一个函数要经过多个函数处理才能得到最终值,这个时候可以把中间过程的函数合并成一个函数。

函数就像是数据的管道,函数组合就是把这些管道连接起来,让数据穿过多个管道形成最终结果

函数组合默认是从右到左执行

//函数组合演示
function compose (f, g) {
    return function (value){
        return f(g(value))
    }
}

function reverse (array) {
    return array.reverse()
}

function first (array) {
    return array[0]
}

const last = compose(first, reverse);

console.log(last([1, 2, 3, 4])) //4

注:此案例只是为了展示组合函数的思路,用组合函数的方式最大的好处可以重用,避免出错。

5、Lodash 组合函数

flow() 或者 flowRight(),他们都可以组合多个函数

flow() 是从左到右运行

flowRight() 是从右到左运行,使用的更多一些

//lodash 中的函数组合的方法 _.flowRight()
const _ = reuqire('lodash')

const reverse = arr => arr.reverse()
const first = arr => arr[0];
const toUpper = s => s.toUpperCase()

const f = _.flowRight(toUpper, first, reverse)
console.log(f(['one', 'two', 'three']))//THREE

//组合函数的原理模拟
//关于reduce的博客:https://www.cnblogs.com/jf-67/p/10768198.html
function compose (...args) {
    return function (value) {
        return args.reverse().reduce(function (acc, fn) {
            return fn(acc)
        }, value)
    }
}

//es6 箭头函数写法
const compose = (...args) => value => args.reverse().reduce((acc,fn) => fn(acc), value)

const f = compose(toUpper, first, reverse)
console.log(f(['one', 'two', 'three']))//THREE

Lodash函数组合---结合律

//lodash 中的函数组合---结合律);
const _ = reuqire('lodash')

//三种写法
const f = _flowRight(_.toUpper, _.first, _.reverse);
const f = _.flowRight(_.toUpper, _.flowRight(_.first, _.reverse))
const f = _.flowRight(_.flowRight(_.toUpper, _.first), _.reverse)
console.log(f(['one', 'two', 'three']))//THREE

6、函数组合调试

const _ = reuqire('lodash')

const trace = _.curry((tab, v) => {
    console.log(tag, v)
    return v
})

//NEVER SAY DIE => never-say-die

const split = _.curry((sep, str) => _.split(str, sep))

const join = _.curry((sep, array) => _.join(array, sep))

const map = _.curry((fn, array) => _.map(array, fn))

const f = _.flowRight(join('-'), trace('map 之后'), map(_.toLower),  trace('split 之后'), split(' '))
console.log(f('NEVER SAY DIE'))

7、Lodash的fp模块


//lodash 的 fp 模块
const fp = reuqire('lodash/fp')

const f = fp.flowRight(fp.join('-'), fp.map(fp.toLower), fp.split(' '))

console.log(f('NEVER SAY DIE'))
//lodash 和 lodash/fp 模块中 map 方法的区别
const fp = reuqire('lodash')

console.log(_.map(['23', '8', '10']), paeseInt) //[23, NAN, 2]  paeseInt接收三个参数(‘元素’,‘索引‘,’数组‘)
parseInt('23', 0, array) //23
parseInt('8', 0, array) //NAN
parseInt('10', 0, array) //2

const fp = reuqire('lodash/fp')
console.log(fp.map(parseInt, ['23', '8', '10'])) //[23, 8, 10]

8、PointFree

我们可以把数据处理的过程定义成与数据无关的合成运算,不需要用到代表数据的那个参 数,只要把简单的运算步骤合成到一起,在使用这种模式之前我们需要定义一些辅助的基本运算函数。

  • 不需要指明处理的数据
  • 只需要合成运算过程
  • 需要定义一些辅助的基本运算函数
//pointFree
//Hello     world => hello_world
const fp = reuqire('lodash')
const f = fp.flowRight(fp.replace(/\s+/g, '_', fp.toLower))
console.log(f('Hello     world')) //hello_world

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值