函数的柯里化简单了解

函数的柯里化

一、概念

接受多个参数的函数转换成接受单一参数的函数的操作。通俗理解为:只传递给函数的一部分参数来调用它,让它返回一个新函数去处理剩下的参数。

测试可用quokka.js(免费版即可) vscode的插件

二、参数定长柯里化

2.1 例一

1
2
3
4
5
6
7
8
9
const add = (...args) => args.reduce((a, b) => a + b);

add(1, 2) // 3

let sum = currying(add);

let addCurryOne = sum(1);
addCurryOne(2) // 3
addCurryOne(3) // 4

用闭包把传入参数保存起来,当传入参数的数量足够执行函数时,就开始执行函数

1
2
3
4
5
6
7
8
9
10
11
function currying(func) {
const args = [];
return function result(...rest) {
if (rest.length === 0) {
return func(...args);
} else {
args.push(...rest);
return result;
}
}
}

image-20200825165013800

2.2 例二

柯里化是在一个函数的基础上变换,得到一个新的预设了参数的函数。最后在调用新函数时候,实际上还是会调用柯里化前的原函数。

而且柯里化得到的新函数可以继续被柯里化,有点递归的感觉,不对不是递归,有点套娃的感觉

image-20200826155358746

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function adds(a, b, c) {
return a + b + c
}

function currying(fn, length) {
length = length || fn.length; // 第一次调用获取函数 fn 参数的长度,后续调用获取 fn 剩余参数的长度
return function () {
arguments //将类数组对象转换成数组
var args = [].slice.call(arguments) // currying返回函数接受的参数
fn
args
console.log(args.length)
length
if (args.length < length) { // 判断参数的长度是否小于 fn 剩余参数需要接收的长度
return currying(fn.bind(this, ...args), length - args.length) // 递归 currying 函数,新的 fn 为 bind 返回的新函数(bind 绑定了 ...args 参数,未执行),新的 length 为 fn 剩余参数的长度
} else {
console.log(fn)
console.log(...args)
return fn.call(this, ...args) // 执行 fn 函数,传入新函数的参数
}
}
}

var addCurry = currying(adds);
console.log(addCurry(2)(3)(4)) // 9
// console.log(addCurry(2, 3)(4)) // 9
// console.log(addCurry(2, 3, 4)) // 9
// addCurry(2)(3, 4) // 9

实现原理都是「用闭包把传入参数保存起来,当传入参数的数量足够执行函数时,就开始执行函数」

三、实际使用

1.bind

MDN的解释

Function.prototype.bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被指定为bind的第一个参数,而其余参数会被指定为新函数的参数,供调用时使用

image-20200827173736428

总结!

柯里化属于函数式编程思想。柯里化时只是返回一个预置参数的新函数,没有立刻执行,实际上在满足条件后才会执行。不污染原函数。

感谢你的打赏哦!