柯里化和偏函数在一些js库中会有实现,如loadsh,underscore等,今天我们来探讨一下~
柯里化会让一个多参数的函数转换成单参数的函数:fn(a,b,c) ——> fn(a)(b)(c )
function add(a, b) {
return a + b;
}
add(1, 2) // 3
// 假设有一个 curry 函数可以做到柯里化
var addCurry = curry(add);
addCurry(1)(2) // 3
它的实际应用如:
// 虽然 ajax 这个函数非常通用,但在重复调用的时候参数冗余
ajax('POST', 'www.test.com', "name=syc")
ajax('POST', 'www.test2.com', "name=syc")
ajax('POST', 'www.test3.com', "name=syc")
//可以做以下优化
var ajaxCurry = curry(ajax);
var post = ajaxCurry('POST');
post('www.test.com', "name=syc");
var postFromTest = post('www.test.com');
postFromTest("name=syc");
作用就是参数复用,减少冗余代码。
一般我们会这么用:
function add(a, b) {
return a + b;
}
var addCurry = curry(add, 1, 2);
addCurry() // 3
//或者
var addCurry = curry(add, 1);
addCurry(2) // 3
//或者
var addCurry = curry(add);
addCurry(1, 2) // 3
现在写它的实现:
function curry(fn, ...params1) {
return function(...params2) {
const params = [...params1, ...params2]
if (params.length < fn.length) {
return curry.call(this, fn, ...params);
}else {
return fn.apply(this, params);
}
}
}
mn
var fn = curry(function(a, b, c) {
console.log([a, b, c]);
});
fn("a", "b", "c") // ["a", "b", "c"]
fn("a", "b")("c") // ["a", "b", "c"]
fn("a")("b")("c") // ["a", "b", "c"]
fn("a")("b", "c") // ["a", "b", "c"]
完结~
下面介绍偏函数:
偏函数则会让一个多参数的函数转换成两个多参数的函数:fn(a,b,c)——> fn(a)(b,c)
举个栗子,partial 函数可以做到如下:
function add(a, b) {
return a + b;
}
add(1, 2) // 3
var addOne = partial(add, 1);
addOne(2) // 3
有点类似bind功能如:
function add(a, b) {
return a + b;
}
var addOne = add.bind(null, 1);
addOne(2) // 3
bind可以绑定一个作用域,改变this指向
partial则不去做这个
尝试写一下:
function partial(fn,...param1) {
return function(...param2) {
return fn.apply(this, [...param1, ...param2]);
};
};
验证下:
function add(a, b) {
return a + b + this.value;
}
// var addOne = add.bind(null, 1);
var addOne = partial(add, 1);
var value = 1;
var obj = {
value: 2,
addOne: addOne
}
obj.addOne(2); // ???
// 使用 bind 时,结果为 4
// 使用 partial 时,结果为 5
没毛病~
完结撒花,有问题留言讨论~~~