函数柯里化介绍

 是什么

维基百科

在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。这个技术由 Christopher Strachey 以逻辑学家 Haskell Curry 命名的,尽管它是 Moses Schnfinkel 和 Gottlob Frege 发明的。

学习资料推荐

==通过函数调用继续返回函数的形式,实现多次接收参数最后统一处理的函数编码形式!==

1. 怎么用

普通写法

function show(_school, _class, _name) {
    return `学校:${_school},班级:${_class},姓名:${_name}`
}
show('技术鸭', '666', '吕布')
show('技术鸭', 666', '赵云')
show('技术鸭', '666', '典韦')

柯里化后

function show(_school) {
    return function (_class) {
        return function (_name) {
            return `技术鸭:${_school},班级:${_class},姓名:${_name}`
        }
    }
}
const f = show('技术鸭')('666')
f('吕布')
f('赵云')
f('典韦')

再举个例子

function show(protocol, domain, port, path) {
    return `${protocol}${domain}:${port}${path}`
}
show('https://', 'www.baidu.com', 80, '/home')
show('https://', 'www.baidu.com', 80, '/news')
show('https://', 'www.baidu.com', 80, '/sports')

2. 转柯里

const lodash = require('lodash')
function show(_school, _class, _name) {
    return `技术鸭:${_school},班级:${_class},姓名:${_name}`
}

const curryShow = lodash.curry(show)
// const r = curryShow('技术鸭', '666', '吕布')
// const r = curryShow('技术鸭')('666', '吕布')
const r = curryShow('技术鸭')('666')('吕布')
console.log(r)

4. 面试题

add(1)(2)(3)(4) => 10
add(1)(2)(3)(4, 5) => 15
add(1)(2)(3)(4)(5) => 15

**意思:**并不是说 add(1)(2)(3)(4) 的返回值是 10,而是 add(1)(2)(3)(4) 参与运算后当做 10 来用

**铺垫:**对象(数组、对象、函数)参与运算,会调用 toString 或 valueOf 得到一个原始值,然后用这个原始值参与运算!

// 对象参与运算,会使用 valueOf 返回的结果进行;如果 valueOf 返回的不是 primitive value,则使用 toString
const obj = {
    valueOf() {
        return []
    },
    toString() {
        return 8
    },
}
console.log(obj + 3)

**思路:**能够持续调用,必然返回函数,能够在参与运算时当成数值,那只能通过 valueOf 或 toString 方法来实现!

function add() {
    // !第一个函数里的参数
    let args = Array.prototype.slice.call(arguments)
    let inner = function () {
        // !把第二个函数的参数加到第一个括号里面
        args.push(...arguments)
        return inner
    }
    inner.toString = () => args.reduce((calc, cur) => calc + cur)
    return inner
}

console.log(add(1)(2)(3)(4) == 10)
console.log(add(1)(2)(3)(4, 5) == 15)
console.log(add(1)(2)(3)(4)(5) == 15)
请登录后发表评论

    没有回复内容