Skip to content

柯里化 #87

@et-hh

Description

@et-hh

定义

简单来说,柯里化就是一种把一个接受多个参数的函数,变成一个能分开接受这些参数的新函数的技术
比如把

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

变成这样:

var newAdd = curry(add)
var step2 = newAdd(1)(2)
console.log(step2(3)) // 6

好处

  • 参数复用
    就比如上面生成的step2,他已经是一个独立的函数,可以接受任何一个数值X,并得出结果:1+2+X,这里1,2两个参数就被复用了
  • 延迟执行
    就是表面意思,比如上面先执行newAdd生成了一个step2函数,但确没有执行最终的add逻辑,直到后面执行step2并传入一个参数才执行最终的逻辑
  • 提前返回
    字面意思,就是说newAdd在执行最终的运算之前,已经返回了一个值step2,这个返回值一定是个函数

柯里化感觉使用场景不是很多,个人感觉最大的作用就是参数复用,一个例子是判断数据类型的

const isType = (type, obj) => Object.prototype.toString.call(obj) === `[object ${type}]`
const isNumber = curry(isType)('Number')
const object = curry(isType)('Object')

实现

const curry = (fn, ...args) => 
    args.length >= fn.length
        ? fn(...args)
        : (..._args) => curry(fn, ...args, ..._args)

网上还有种说法是

function multi() {
    var args = Array.prototype.slice.call(arguments);
    var fn = function() {
        var newArgs = args.concat(Array.prototype.slice.call(arguments));
        return multi.apply(this, newArgs);
     }
    fn.toString = function() {
        return args.reduce(function(a, b) {
            return a * b;
        })
    }
    return fn;
}

这种方法我觉得根本不是正确的解法,因为无论如何最终返回的都是一个函数,网上的说法是利用toString去得出值,但那还不得手动转一下?比如multi(1)(2).toString()?或者+multi(1)(2),这我感觉有点扯淡了,一个函数不实现该实现的功能,还要使用者额外处理

参考

https://juejin.cn/post/6844904093467541517
https://juejin.cn/post/6844903665308794888

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions